2016-05-03 10 views
0

Ich lese durch Scala-by-Beispiel (2014) von Martin Odersky. Auf Seite 61 heißt es, dass eine Funktion vom Typ String zum Typ Int als eine Instanz des Merkmals Function1 [String, Int] dargestellt wird. Wo Function1 ist wie folgt definiert:Welche Funktion hat der Untertyp in diesem Scala-Beispiel?

trait Function1[-A,+B] {def apply(x: A): B}

Es wird auch gesagt, weiter unten, dass

S => T ein Subtyp von S '=> T', vorausgesetzt, S‘ist ein Subtyp von S und T ist ein Subtyp von T '.

Er verwendet das folgende Codebeispiel: val f: (AnyRef => Int) = x => x.hashCode() val g: (String => Int) = f g("abc")

So, hier ist meine Frage bitte. Da String ein Subtyp von AnyRef ist, nehme ich an, dass in diesem Beispiel f einen Subtyp von g darstellt. Ist das korrekt? Wenn ja, erläutern Sie bitte die Logik in dieser Bestimmung.

Antwort

3

Wenn V ein Subtyp von U ist, dann kann V stehen in jedem Ort, dass U kann.

Wenn Sie eine AnyRef => Int haben, können Sie sie jederzeit verwenden, wenn Sie eine String => Int verwenden könnten? Ja! A String ist ein AnyRef, so dass Sie es übergeben können.

So ist AnyRef => Int ein Untertyp von String => Int. Diese Beziehung (die vom Normalzustand "rückwärts" ist) wird dadurch beschrieben, dass Funktionen in ihren Argumenten contravariant sind.

die besagten, die Instanzenf und g müssen keine Beziehung haben. Aber ihre Typen tun es.

+0

yup. kurz und einfach - macht Sinn. Danke! – TalBeno

0

f und g Funktionen und Funktionen haben eine Art Varianz, die für Subtypen und geordneten Typen von Typparametern ermöglicht: http://docs.scala-lang.org/tutorials/tour/variances.html

den folgenden Code in dem scala Terminal ausführen, werden Sie das gleiche Ergebnis wie das Beispiel ausgeführt wird.

g als fuction vom Typ (AnyRef => Int) erklärt, die Funktion implementieren würde, wie:

val f = new Function[AnyRef /*or any supertype*/,Int /*or any subType type*/] { 
    def apply(x: AnyRef): Int = x.hashCode() 
} 

Es als eine Funktion definiert, die AnyRef in einem Parameter des Typs nimmt, kehrt ein Int .

g ist dann als eine Funktion definiert, die eine String übernimmt und eine Int zurückgibt. Es ist gleich f gesetzt, so wird es dies:

val g = new Function[String /*Supertype of AnyRef*/, Int] { 
    def apply(x: String): Int = x.hashCode() 
} 

Obwohl g nicht um eine neue Funktion in diesem Fall ist. g ist nur ein weiterer Hinweis auf f. Im Wesentlichen wird g in Function[String, Int] typisiert.

Edit: Da AnyVal ein Subtyp von Int ist, können Sie dies auch tun:

val gg: (String => AnyVal) = f 
Verwandte Themen