2017-10-16 4 views
0

Ich lerne scala implicits. Im folgenden Beispielcode, implizite gelten nicht automatisch aufgerufen zu werden:implizite Methode in scala Klasse

package learn 

object ImplicitApplyInClass { 

    def main(args: Array[String]): Unit = { 


    implicit val ss = "abc" 

    //This is working 
    val a = A(1).apply.toUpperCase 

    //This is giving compile time error 
    //val b = A(1).toUpperCase 
    } 
} 

case class A(id: Int) { 
    implicit def apply(implicit s: String) = { 
    s.toUpperCase  
    } 
} 

Bitte legen nahe, warum gelten nicht implizit aufgerufen zu werden, wenn der implizite Parameter in thr Umfang zur Verfügung steht?

Antwort

1

können Sie leere Parameterliste hinzufügen und dies funktionieren wird:

case class A(id: Int) { 
    implicit def apply()(implicit s: String) = { 
     s.toUpperCase 
    } 
    } 

    val b = A(1)().toUpperCase 
    println(b) // ABC 

Hier apply nicht als implizite Konvertierung funktioniert.

Eine implizite Konvertierung vom Typ ST einzugeben ist durch einen impliziten Wert definiert, den Funktionstyp hat S => T oder durch ein implizites Verfahren umwandelbar auf einen Wert dieses Typs.

Implizite Konvertierungen sind in zwei Situationen angewendet:

• Wenn ein Ausdruck e vom Typ S und S entspricht nicht dem erwarteten Ausdruck Typ T.

• In einer Auswahl e.m mit e vom Typ S, wenn der Wähler m kein Mitglied in S bezeichnen ist.

Im ersten Fall wird eine Umwandlung c wird, für die zu e anwendbar gesucht und dessen Ergebnistyp entspricht T. Im zweiten Fall wird nach einer Konvertierung c gesucht, die für e gilt und deren Ergebnis ein Element mit dem Namen m enthält.

Von here.

In Ihrem Code ist es keiner der Fälle.

Fall 1 ist nicht anwendbar, da applyString => String ist. Fall 2 ist nicht anwendbar, da es keine implizite Umwandlung gibt A => { def toUpperCase }.

0

Sie können dies versuchen:

object ImplicitApplyInClass { 
    def main(args: Array[String]): Unit = { 
    implicit val ss = "abc" 
    val b = A(1).toUpperCase 
    println(b) 
    } 
} 
object A { 
    implicit def f(a: A)(implicit s: String): String = s 
} 
case class A(id: Int) 
0

Wenn Sie eine implizite Methode definieren innerhalb class A dies als Definition eine implizite Konvertierung von dieser Klasse gar nicht das gleiche ist.

Es ist verwendbar als implizite in dem Anwendungsbereich, wo er definiert ist, aber es ist eine implizite Konvertierung String-String, die der Compiler keinen Grund implizit zu verwenden hat.