Die Chapter 2. Type Less, Do More des Programming Scala Buch erwähnt:
Wenn Explicit Geben Sie Anmerkungen erforderlich sind.
In der Praxis haben Sie explizite Typenannotationen für die folgenden Situationen bieten:
Methode Rückgabewerte in den folgenden Fällen:
- Wenn Sie explizit Rückkehr in einer Methode aufrufen (auch bei das Ende).
- Wenn eine Methode rekursiv ist.
- Wenn eine Methode überladen ist und eine der Methoden eine andere aufruft. Die aufrufende Methode benötigt eine Annotation des Rückgabetyps.
- Wenn der abgeleitete Rückgabetyp allgemeiner ist, als Sie beabsichtigten, z. B.
Any
.
Beispiel:
// code-examples/TypeLessDoMore/method-nested-return-script.scala
// ERROR: Won't compile until you put a String return type on upCase.
def upCase(s: String) = {
if (s.length == 0)
return s // ERROR - forces return type of upCase to be declared.
else
s.toUpperCase()
}
Überladene Methoden kann manchmal einen expliziten Rückgabetyp erfordern. Wenn eine solche Methode eine andere aufruft, müssen wir einen Rückgabetyp zu demjenigen hinzufügen, der den Aufruf ausführt, wie in diesem Beispiel.
// code-examples/TypeLessDoMore/method-overloaded-return-script.scala
// Version 1 of "StringUtil" (with a compilation error).
// ERROR: Won't compile: needs a String return type on the second "joiner".
object StringUtil {
def joiner(strings: List[String], separator: String): String =
strings.mkString(separator)
def joiner(strings: List[String]) = joiner(strings, " ") // ERROR
}
import StringUtil._ // Import the joiner methods.
println(joiner(List("Programming", "Scala")))
Die beiden Methoden joiner
verketten zusammen eine List
von Strings.
Die erste Methode nimmt auch ein Argument für die Trennzeichenfolge.
Die zweite Methode ruft die erste mit einem "default" Trennzeichen eines einzelnen Platzes auf.
Wenn Sie dieses Skript ausführen, erhalten Sie den folgenden Fehler.
... 9: error: overloaded method joiner needs result type
def joiner(strings: List[String]) = joiner(strings, "")
Da das zweite Verfahren joiner
die ersten Aufforderungen, es erfordert einen expliziten String
Rückgabetyp.Es sollte wie folgt aussehen:
def joiner(strings: List[String]): String = joiner(strings, " ")
Grundsätzlich den Rückgabetyp Angabe kann auch eine gute Übung sein, obwohl Scala es ableiten kann.
Randall Schulz Kommentare:
Als eine Frage der (mein persönlicher) Stil, gebe ich expliziten Rückgabetypen für alle, aber die meisten einfachen Methoden (im Grunde, Einzeiler ohne bedingte Logik).
Denken Sie daran, wenn Sie den Compiler auf den Ergebnistyp einer Methode schließen lassen, ist dies möglicherweise genauer als gewünscht. (Zum Beispiel HashMap anstelle von Karte.)
Und da Sie die minimale Schnittstelle in Ihrem Rückgabetyp aussetzen möchten (siehe zum Beispiel das SO question), diese Art von Folgerung könnte in die Quere kommen.
Und über das letzte Szenario („Wenn der gefolgert Rückgabetyp allgemeiner sein würde, als Sie gedacht“), Ken Bloom fügt hinzu:
den Rückgabetyp angeben, wenn Sie die Compiler überprüfen mögen dass Code in der Funktion gibt den Typen Sie erwartet
(den fehlerhaften Code, der ein „allgemeine als erwarteten Rückgabetyp auslöst war:
// code-examples/TypeLessDoMore/method-broad-inference-return-script.scala
// ERROR: Won't compile. Method actually returns List[Any], which is too "broad".
def makeList(strings: String*) = {
if (strings.length == 0)
List(0) // #1
else
strings.toList
}
val list: List[String] = makeList() // ERROR
, die ich falsch interpretiert und List [Alles], weil eine leere Liste zurückkehrt, aber Ken rief es aus:
List(0)
erstellen keine Liste mit 0 Elementen.
Erzeugt ein List[Int]
mit einem Element (der Wert 0).
Also eine List[Int]
auf einer bedingten Verzweigung und eine List[String]
auf der anderen bedingten Verzweigung verallgemeinern zu List[Any]
.
In diesem Fall der Typer ist nicht allzu allgemein - es ist ein Fehler im Code.
)
Als eine Frage der (mein persönlicher) Stil, gebe ich expliziten Rückgabetypen für alle, aber die meisten einfachen Methoden (im Grunde, Einzeiler ohne bedingte Logik). Denken Sie daran, dass der Compiler dann, wenn Sie den Ergebnistyp einer Methode ableiten, möglicherweise genauer ist als Sie möchten. (Z. B. 'HashMap' anstelle von' Map'). –
@Randall ja, guter Punkt (der Rückgabetyp ist zu spezifisch). – Jesper