2014-10-24 3 views
15

Ergebnistyp einer impliziten Umwandlung muss spezifischer als AnyRef

def h(a: AnyRef*) = a.mkString(",") 
h: (a: AnyRef*)String 

Lassen und so

h("1","2") 
res: String = 1,2 

jedoch 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) 
       ^

Dies ist zumindest in Scala 2.11. 1 und 2.11.1. Fragen Sie nach einer Problemumgehung.

+4

Das scala repl auf scala 2.10.X gibt eine viel aussagekräftige Antwort zurück: 'Fehler: Typenkonflikt; gefunden: Int (1) erforderlich: AnyRef Hinweis: eine implizite existiert von scala.Int => java.lang.Integer, aber Methoden geerbt von Object werden mehrdeutig gerendert. Dies soll ein implizites Bucket vermeiden, das scala.Int in AnyRef konvertieren würde. Sie können eine Typbezeichnung verwenden: 'x: java.lang.Integer'. h (1,2) ' –

+0

Übrigens können Sie das Problem mit' val x: AnyRef = 42' reproduzieren –

Antwort

12

Sie können das Problem reproduzieren einfach mit:

val x: AnyRef = 42 

Hier ist der relevante pull request on github, die die Änderung eingeführt

Der Grund ist, dass aus Sicherheitsgründen einige implizite Konvertierungen explizit deaktiviert sind, nämlich dann, wenn die Umwandlung geht T-U ist deaktiviert, wenn:

T <: Null 

oder

AnyRef <: U 

In Ihrem speziellen Fall bedeutet dies, dass ein Int (was kein AnyRef ist) nie zu AnyRef umgewandelt werden.

Wenn Sie sowohl Int als auch String akzeptieren müssen, können Sie stattdessen akzeptieren. Da jedes scala-Objekt von Any erbt, ist keine implizite Konvertierung erforderlich.

def h(a: Any*) = a.mkString(",") 
2

Ich glaube nicht, dass Sie AnyRef hier verwenden möchten. Ich denke du willst Any.

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

scala> h(1,2) 
res0: String = 1,2 

Der Grund dafür ist, dass der numerische Wert 5 ein Int ist, aber AnyRef ist Object Äquivalenz Java. Um diese Methode aufzurufen, müsste es ein java.util.Integer sein.

21

Der Grund dafür ist, dass die numerischen Typ der Literale 1 und 2, die IntAnyVal erstreckt, die sich wiederum Any erstreckt. Auf der anderen Seite String erstreckt sich AnyRef, die wiederum Any erstreckt. So wie Sie sehen können (Int Elternteil) nicht AnyRef erweitern. Sie können dies auf eine von zwei Arten lösen.

Die erste ändert den Typ von AnyRef zu Any wie von Nate beschrieben.

Die zweite verwendet eine Typbezeichnung für die Literale 1 und 2, so dass sie vom Typ java.lang.Integer betrachtet werden, der java.lang.Object erweitert. Beachten Sie auch, dass AnyRef nur ein Alias ​​für java.lang.Object ist.Also, mit Ihrer Definition sollte folgende Arbeiten:

scala> h(1: java.lang.Integer, 2: java.lang.Integer) 
res2: String = 1,2 

Weiterer Informationen über Scala Hierarchy

Verwandte Themen