隐式转换的结果类型必须比AnyRef更具体

elm*_*elm 22 scala

def h(a: AnyRef*) = a.mkString(",")
h: (a: AnyRef*)String
Run Code Online (Sandbox Code Playgroud)

所以

h("1","2")
res: String = 1,2
Run Code Online (Sandbox Code Playgroud)

然而, h(1,2)

error: the result type of an implicit conversion must be more specific than AnyRef
              h(1,2)
                ^
error: the result type of an implicit conversion must be more specific than AnyRef
              h(1,2)
                  ^
Run Code Online (Sandbox Code Playgroud)

这至少在Scala 2.11.1和2.11.1中.询问解决方法.

lam*_*sta 28

原因是文字1和2的数字类型是Int扩展的AnyVal,而后者又扩展了Any.另一方面,String延伸AnyRef又延伸Any.所以你可以看到AnyVal(Int'的父母)没有扩展AnyRef.您可以通过以下两种方式之一解决此问题.

第一个是将类型AnyRef改为AnyNate所描述的.

第二个是对文字1和2使用类型归属,因此它们被认为是java.lang.Integer扩展的类型java.lang.Object.另请注意,这AnyRef只是一个别名java.lang.Object.因此,使用您的定义,以下内容应该有效:

scala> h(1: java.lang.Integer, 2: java.lang.Integer)
res2: String = 1,2
Run Code Online (Sandbox Code Playgroud)

有关Scala Hierarchy的更多信息


Gab*_*lla 22

您可以使用以下方法重现问题:

val x: AnyRef = 42
Run Code Online (Sandbox Code Playgroud)

这是引入更改的github上的相关pull请求

理由是,出于安全原因,一些隐式转换是明确禁用,也就是当转换从去TU如果被禁用:

T <: Null
Run Code Online (Sandbox Code Playgroud)

要么

AnyRef <: U
Run Code Online (Sandbox Code Playgroud)

在您的特定情况下,这意味着永远不会转换为Int(不是AnyRef)AnyRef.

如果你需要同时接受IntString,你可以考虑接受Any.由于每个scala对象都继承自Any,因此不需要隐式转换.

def h(a: Any*) = a.mkString(",")
Run Code Online (Sandbox Code Playgroud)


Mat*_*hew 6

AnyRef通过执行以下操作将您的变量转换为:

h(1.asInstanceOf[AnyRef], 2.asInstanceOf[AnyRef])
Run Code Online (Sandbox Code Playgroud)

为什么?

在 scala 中,并非所有东西都像在 java 中那样扩展Object(又名AnyRef)。特别是原语扩展AnyVal,所以如果你的函数需要一个AnyRef你需要强制转换/转换/限制你的scala变量。

这里有一个很好的讨论:Any、AnyVal、AnyRef、Object 之间的关系是什么以及它们在 Java 代码中使用时如何映射?


Nat*_*ate 5

我不认为你想在AnyRef这里使用。我想你想要Any

scala> def h(a: Any*) = a.mkString(",")
h: (a: Any*)String

scala> h(1,2)
res0: String = 1,2
Run Code Online (Sandbox Code Playgroud)

原因是数值5是一个Int,但是AnyRef是java的Object等价。因此,要调用该方法,它需要是一个 java.util.Integer。