【问题标题】:Scala extreme destructuring?Scala 极端解构?
【发布时间】:2015-03-08 14:07:20
【问题描述】:

我有这行代码,我使用我知道的最惯用的方式来解构从函数返回的对象:

val (a, b) = foo match { case MyObjectType(a, b) => (a, b) }

对象的原型是:

case class MyObjectType(Type1: SomeType1, Type2: SomeType2)

我当然可以:

val returnType = foo
val (a, b) = (returnType.a, returnType.b)

但后者是陈述同一问题的完全不同的形式——这确实不优雅。 Scala 宏能否提供一个简洁的习语?也许允许类似以下的语法:

val (a, b) = foo deconstruct { MyObjectType(a, b) => (a, b) } // merely more shorthand, like scala allows e.g. within a map block

val (a, b) = tuplize(foo)                                     // assumes tuplize can iterate the vals of MyObjectType

tupleResult(a, b) = foo                                       // radical macro api exploring the limits of macro safety...

tupledVars(foo)                                               // macro extreme

【问题讨论】:

    标签: scala macros destructuring


    【解决方案1】:

    有点答案,但这不会给你一个元组。你知道这行得通吗:

    val MyObjectType(a,b) = foo

    此外,如果您正在解构可变参数 T*,您可以执行如下代码:

    val Array(first, second, _*) = Array(1,2,3,4)
    val Array(fst, snd, _*) = Array(1,2)
    

    如果你想要元组直接看In Scala, is there an easy way to convert a case class into a tuple?

    【讨论】:

    • 谢谢,这比元组好,我在想元组只是因为我认为解决方案会通过一个,但这可以完成工作!我想知道它是如何在幕后工作的……顺便说一句,引用的答案的答案真的很差。这个解决方案更有用,但我想知道它为什么有效,如果您愿意详细说明的话。
    【解决方案2】:

    您可能希望通过Shapeless 探索泛型编程

    scala> import shapeless._, syntax.std.product._, syntax.std.tuple._
    import shapeless._
    import syntax.std.product._
    import syntax.std.tuple._
    
    scala> case class Foo(i: Int, s: String, b: Boolean)
    defined class Foo
    
    scala> val foo = Foo(1, "foo", true)
    foo: Foo = Foo(1,foo,true)
    

    现在在Generic 的帮助下,我们可以将Foo 转换为HList 并返回

    scala> Generic[Foo].to(foo)
    res0: shapeless.::[Int,shapeless.::[String,shapeless.::[Boolean,shapeless.HNil]]] = 1 :: foo :: true :: HNil
    
    scala> Generic[Foo].from(res0)
    res1: Foo = Foo(1,foo,true)
    

    或者你可以使用syntax.std.product提供的不错的语法糖

    scala> foo.toHList
    res2: this.Repr = 1 :: foo :: true :: HNil
    
    scala> foo.toTuple
    res3: (Int, String, Boolean) = (1,foo,true)
    

    请参阅feature overviewexamples 了解更多信息。

    【讨论】:

    • 谢谢,但我暂时避免混入无形中,直到我更好地理解它在引擎盖下的作用,特别是它的习语对性能的影响
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2018-10-05
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多