Let
def h(a: AnyRef*) = a.mkString(",")
h: (a: AnyRef*)String
and so
h("1","2")
res: String = 1,2
However, 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)
^
This is at least in Scala 2.11.1 and 2.11.1. To ask on a workaround.
The reason is that the numeric type of the literals 1 and 2 is Int
which extends AnyVal
which, in turn, extends Any
. On the other hand String
extends AnyRef
which, in turn, extends Any
. So as you can see AnyVal
(Int
's parent) does not extend AnyRef
. You can solve this in one of two ways.
The first one is changing the type from AnyRef
to Any
as described by Nate.
The second one is using a type ascription for the literals 1 and 2 so that they are considered of type java.lang.Integer
which extends java.lang.Object
. Note also that AnyRef
is just an alias for java.lang.Object
. So, using your definition the following should work:
scala> h(1: java.lang.Integer, 2: java.lang.Integer)
res2: String = 1,2
More info on Scala Hierarchy
You can reproduce the issue simply with:
val x: AnyRef = 42
Here's the relevant pull request on github that introduced the change
The rationale is that for security reasons some implicit conversions are explicitly disabled, namely when the conversion goes from T
to U
is disabled if:
T <: Null
or
AnyRef <: U
In your specific case, this means that an Int
(which is not an AnyRef
) will never be converted to AnyRef
.
If you need to accept both Int
and String
, you can consider accepting Any
instead. Since every scala object inherits from Any
, there's no implicit conversion needed.
def h(a: Any*) = a.mkString(",")
Cast your variable to AnyRef
by doing something like this:
h(1.asInstanceOf[AnyRef], 2.asInstanceOf[AnyRef])
Why?
In scala not everything extends Object
(aka AnyRef
) in the way that it would in java. Specifically primitives extend AnyVal
, so if your function requires an AnyRef
you'll need to cast / convert / restrict your scala variables.
There's a good discussion here: What are the relationships between Any, AnyVal, AnyRef, Object and how do they map when used in Java code?
I don't think you want to use AnyRef
here. I think you want Any
.
scala> def h(a: Any*) = a.mkString(",")
h: (a: Any*)String
scala> h(1,2)
res0: String = 1,2
The reason is that the numeric value 5
is an Int, but AnyRef
is java's Object
equivalence. So to invoke that method it would need to be a java.util.Integer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With