Scala 极端解构?
Scala extreme 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
有点答案,但不会给你一个元组。你知道这行得通吗:
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?
您可能希望使用 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 overview and examples。
我有这行代码,我使用我所知道的最惯用的方式来解构从函数返回的对象:
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
有点答案,但不会给你一个元组。你知道这行得通吗:
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?
您可能希望使用 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 overview and examples。