>我有以下方法:
def lift[P <: Product, L <: HList](params: P)(implicit hl: Generic.Aux[P, L]) = {
directive[L](_(hl to params))
}
如果我传递两个以上的参数,它就可以完美地工作:
val result = lift("string", 'a', 10) // compiles
val result2 = list(true, 5) // compiles
但是当我传递一个参数时,它无法解决隐式问题:
val failes = lift("string")
它找不到[String, Nothing]
的通用隐式,为什么它在其他情况下有效?
您看到的是自动更新的结果,这是一个 Scala(错误)功能,当没有具有适当数量的值(在本例中为两个)的lift
方法时,会导致lift(true, 5)
被解析为lift((true, 5))
。编译器不会自动将单个值包装在Tuple1
中,但是,您只会收到编译器错误。
例如,有关自动更新的更多详细信息,请参阅此答案,并且由于某些原因,此线程自动更新包含在您的语言中是一件可怕的事情。
有几种可能的解决方法。第一种是创建从值到Tuple1
的隐式转换,如本答案所示。我个人不推荐这种方法 - 您在代码中引入的每个隐式转换都是雷区中的另一个地雷。
相反,我建议完全避免自动升级。明确地写出list((true, 5))
- 你得到很多额外的清晰度,而代价是只多了几个字符。不幸的是,没有可比的文字支持Tuple1
,所以你必须写出lift(Tuple1("string"))
,但即使这样也不错,如果你真的想要,你可以定义一个新的liftOne
方法来为你做这件事。