作为一个练习,我试图看看我是否可以List[Any]使用无形的方法将其"投射"到案例类中.
我想要实现的一个非常基本的例子:
case class Foo(i: Int, j: String)
val foo: Option[Foo] = fromListToCaseClass[Foo]( List(1:Any, "hi":Any) )
Run Code Online (Sandbox Code Playgroud)
以下是我如何塑造我的解决方案(这可能非常不合适):
def fromListToCaseClass[CC <: Product](a: List[Any]): Option[CC] = a.toHList[???].map( x => Generic[CC].from(x) )
Run Code Online (Sandbox Code Playgroud)
这是我的推理:
我知道你可以从case类转到HList [T](CC - > HList [T]); 其中T是HList的类型.我也知道你可以从列表中创建一个HList(list - > Option [HList]),只要你知道HList的类型.最后我知道你可以从HList转到案例类(HList - > CC).
CC -> HList[T]
list -> Option[HList[T]] -> Option[CC]
Run Code Online (Sandbox Code Playgroud)
我想知道这是否有意义,或者我是否离开这里.我们能做到这一点吗?还有其他建议吗?谢谢!
这可以使用无形Generic和FromTraversable类型类非常直接地完成,
import scala.collection.GenTraversable
import shapeless._, ops.traversable.FromTraversable
class FromListToCaseClass[T] {
def apply[R <: HList](l: GenTraversable[_])
(implicit gen: Generic.Aux[T, R], tl: FromTraversable[R]): Option[T] =
tl(l).map(gen.from)
}
def fromListToCaseClass[T] = new FromListToCaseClass[T]
Run Code Online (Sandbox Code Playgroud)
(由于Scala在混合显式和推断类型参数方面的尴尬,这里有一些偶然的复杂性:我们想要T明确指定,但已R推断出我们).
样本REPL会话......
scala> case class Foo(i: Int, j: String)
defined class Foo
scala> fromListToCaseClass[Foo](List(23, "foo"))
res0: Option[Foo] = Some(Foo(23,foo))
scala> fromListToCaseClass[Foo](List(23, false))
res1: Option[Foo] = None
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
923 次 |
| 最近记录: |