让
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)
理由是,出于安全原因,一些隐式转换是明确禁用,也就是当转换从去T到U如果被禁用:
T <: Null
Run Code Online (Sandbox Code Playgroud)
要么
AnyRef <: U
Run Code Online (Sandbox Code Playgroud)
在您的特定情况下,这意味着永远不会转换为Int(不是AnyRef)AnyRef.
如果你需要同时接受Int和String,你可以考虑接受Any.由于每个scala对象都继承自Any,因此不需要隐式转换.
def h(a: Any*) = a.mkString(",")
Run Code Online (Sandbox Code Playgroud)
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 代码中使用时如何映射?
我不认为你想在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。