将单个参数转换为具有无形状泛型的 HList



>我有以下方法:

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方法来为你做这件事。

最新更新