让
def h(a: AnyRef*) = a.mkString(",")
h: (a: AnyRef*)String
等等
h("1","2")
res: String = 1,2
但是,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)
^
至少在Scala 2.11.1和2.11.1中。 要求解决方法。
答案 0 :(得分:26)
原因是文字1和2的数字类型是Int
,它扩展了AnyVal
,而Any
则扩展了String
。另一方面,AnyRef
扩展Any
,而AnyVal
则扩展Int
。因此,您可以看到AnyRef
(AnyRef
' s的父级)不会延伸Any
。您可以通过以下两种方式之一解决此问题。
第一个是将类型从java.lang.Integer
更改为java.lang.Object
,如Nate所述。
第二个是对文字1和2使用类型归属,因此它们被认为是AnyRef
类型,它扩展了java.lang.Object
。另请注意,scala> h(1: java.lang.Integer, 2: java.lang.Integer)
res2: String = 1,2
只是{{1}}的别名。因此,使用您的定义,以下内容应该有效:
{{1}}的更多信息
答案 1 :(得分:19)
您可以使用以下方式重现问题:
val x: AnyRef = 42
以下是介绍此更改的相关pull request on github
基本原理是出于安全原因,明确禁用了一些隐式转换,即如果符合以下条件,则转换从T
转到U
时将被禁用:
T <: Null
或
AnyRef <: U
在您的具体情况下,这意味着Int
(不是AnyRef
)永远不会转换为AnyRef
。
如果您需要同时接受Int
和String
,则可以考虑接受Any
。由于每个scala对象都继承自Any
,因此不需要隐式转换。
def h(a: Any*) = a.mkString(",")
答案 2 :(得分:2)
我不认为你想在这里使用AnyRef
。我想你想要Any
。
scala> def h(a: Any*) = a.mkString(",")
h: (a: Any*)String
scala> h(1,2)
res0: String = 1,2
原因是数值5
是Int,但AnyRef
是java的Object
等价。因此,要调用该方法,它需要是一个java.util.Integer。
答案 3 :(得分:2)
通过执行以下操作将变量设置为AnyRef
:
h(1.asInstanceOf[AnyRef], 2.asInstanceOf[AnyRef])
为什么?
在scala中,并非所有内容都像在Java中那样扩展Object
(又名AnyRef
)。具体来说,原语会扩展AnyVal
,因此,如果您的函数需要AnyRef
,则需要强制转换/转换/限制scala变量。