问题描述
我想知道在给定的 case class
中是否存在特定的类成员.
I want to find out if a particular class member is present in a given case class
or not.
以下确实给了我那个答案,在编译时失败,这是正确的.(归功于 Travis Brown)
Following does give me that answer, failing at compile time which is right. (credit to 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
方法,有没有办法让它与泛型类型 一起工作
?
Now if I don't have a concrete type but T
to pass into getIntId
method, is there a way to get this to work with generic type T
?
更新假设有一个名为 findIdFromType
的方法,如下所述,它接受类型 T
(其中 T
将始终是某个 case 类代码>).有可能完成这项工作吗?
UpdateSay have a method called findIdFromType
as described below which takes in type T
(where T
will always be a some case class
). is it possible to make this work?
def findIdFromType[T](t:T) = {
getIntId(t) //as expected doesn't compile
}
推荐答案
getIntId
需要两个隐式参数.
如果需要在本地方法的上下文中调用它,则需要证明这些参数存在于这样的上下文中.
If you need to call it in the context of a local method, you need to prove that those parameters exist in such context.
为了做到这一点,你必须像这样传播隐性证据
In order to do so, you have to propagate the implicit evidence, like this
def findIdFromType[A, R <: HList](a: A)(implicit
gen: LabelledGeneric.Aux[A, R],
sel: Selector.Aux[R, Witness.`'id`.T, Int]): Int = getIntId(a)
这当然是一个完全没用的例子,但如果你想在包装方法内部执行其他操作,这是要走的路:传播隐式证据.
This of course is a completely useless example, but in case you want to perform other operations inside the wrapping method, this is the way to go: propagate the implicit evidence.
这篇关于避免具有无形替代品的结构类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!