我想做类似以下的事情:
val foo = List[B <% JValue] = 42 :: "hello" : Nil
让编译器知道我的列表成员可以转换为JValues.
但是,这不编译.我不能满足于List[Any]因为我必须使用其成员,其中可以转换为JValues的值是预期的,例如:
def fun[A <% JValue](x: List[A]) = ...
有什么方法可以解决这个问题吗?
你可以写
val foo: List[JValue] = List(42, "hello")
Run Code Online (Sandbox Code Playgroud)
如果没有从这些类型的隐式转换,JValue那么它将不会键入check.
不幸的是你不能写它,42 :: "hello" :: Nil因为编译器不够聪明,不知道你想要在每个术语上应用转换(你可以在每个术语上添加一个类型注释,但这很麻烦).每个::方法都必须以某种方式向前看到表达式的结尾,以检查某个后来的方法是否适合类型参数.
但是,如果要添加自己的时髦运算符,可以约束下面允许的类型:::
implicit class pimp(xs: List[JValue]) {
def |: (x: JValue) = x :: xs
}
Run Code Online (Sandbox Code Playgroud)
之后你可以写这样的东西:
val foo = 42 |: "hello" |: Nil
// type is List[JValue]
Run Code Online (Sandbox Code Playgroud)
(我尝试参数化这个,以便它可以推断出最具体的常见类型,::但是有一个上限,编译器不想玩球 - 请看这里.也许有更多Scala-fu的人可以修复它,如果是的话可能.)