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