我想知道某个特定的成员是否存在于给定的case class
中。
以下确实给了我答案,在编译时失败,这是正确的。 (信用Travis Brown)
scala> def getIntId[A, R <: HList](a: A)(implicit
| gen: LabelledGeneric.Aux[A, R],
| sel: Selector.Aux[R, Witness.`'id`.T, Int]
| ): Int = sel(gen.to(a))
case class Foo(id: String)
case class Bar(id: Int, name: String)
scala> getIntId(Bar(123, "bar"))
res3: Int = 123
scala> getIntId(Foo("12345"))
<console>:15: error: could not find implicit value for parameter sel: shapeless.ops.record.Selector.Aux[R,Symbol with shapeless.tag.Tagged[String("id")],Int]
getIntId(Foo("12345"))
现在,如果我没有具体类型但T
传递给getIntId
方法,有没有办法让它与泛型类型T
一起使用?
更新
假设有一个名为findIdFromType
的方法,如下所述,它采用T
类型(其中T
将始终为某个case class
)。是否有可能使这项工作?
def findIdFromType[T](t:T) = {
getIntId(t) //as expected doesn't compile
}
答案 0 :(得分:2)
getIntId
需要两个隐式参数。
如果需要在本地方法的上下文中调用它,则需要证明这些参数存在于此类上下文中。
为了做到这一点,你必须传播隐含的证据,比如
def findIdFromType[A, R <: HList](a: A)(implicit
gen: LabelledGeneric.Aux[A, R],
sel: Selector.Aux[R, Witness.`'id`.T, Int]): Int = getIntId(a)
这当然是一个完全没用的例子,但是如果你想在包装方法中执行其他操作,这就是要走的路:传播隐式证据。