Scala极端解构?

时间:2015-03-08 14:07:20

标签: scala macros destructuring

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

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

2 个答案:

答案 0 :(得分:9)

有点回答,但这不会给你一个元组。你知道吗:

val MyObjectType(a,b) = foo

此外,如果您正在解构varargs 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?

答案 1 :(得分:0)

您可能希望使用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