Wenn Sie in Go einen neuen Typ definieren, z.
type MyInt int
Sie können a dann nicht MyInt
an eine Funktion übergeben, die ein int erwartet, oder umgekehrt:
func test(i MyInt) {
//do something with i
}
func main() {
anInt := 0
test(anInt) //doesn't work, int is not of type MyInt
}
Fein. Aber warum gilt das nicht auch für Funktionen? z.B:
type MyFunc func(i int)
func (m MyFunc) Run(i int) {
m(i)
}
func run(f MyFunc, i int) {
f.Run(i)
}
func main() {
var newfunc func(int) //explicit declaration
newfunc = func(i int) {
fmt.Println(i)
}
run(newfunc, 10) //works just fine, even though types seem to differ
}
Jetzt beschwere ich mich nicht, weil ich dadurch nicht explizit newfunc
in Typ umwandeln muss MyFunc
, wie ich es im ersten Beispiel tun müsste. es scheint nur inkonsistent. Ich bin sicher, es gibt einen guten Grund dafür; kann mich jemand aufklären?
Der Grund, den ich frage, ist hauptsächlich, dass ich einige meiner ziemlich langen Funktionstypen auf diese Weise kürzen möchte, aber ich möchte sicherstellen, dass dies erwartet und akzeptabel ist :)
type
ist in Go eher nützlich als in Scala. Scala hat leider nur Typ-Aliase.Antworten:
Es stellt sich heraus, dass dies ein Missverständnis ist, das ich über den Umgang von Go mit Typen hatte, das durch Lesen des relevanten Teils der Spezifikation behoben werden kann:
http://golang.org/ref/spec#Type_identity
Die relevante Unterscheidung, die mir nicht bekannt war, war die von benannten und unbenannten Typen.
Benannte Typen sind Typen mit einem Namen, z. B. int, int64, float, string, bool. Darüber hinaus ist jeder Typ, den Sie mit 'type' erstellen, ein benannter Typ.
Unbenannte Typen sind solche wie [] string, map [string] string, [4] int. Sie haben keinen Namen, sondern lediglich eine Beschreibung, die ihrer Struktur entspricht.
Wenn Sie zwei benannte Typen vergleichen, müssen die Namen übereinstimmen, damit sie austauschbar sind. Wenn Sie einen benannten und einen unbenannten Typ vergleichen, können Sie loslegen, solange die zugrunde liegende Darstellung übereinstimmt !
zB bei folgenden Typen:
Folgendes ist ungültig:
Folgendes ist in Ordnung:
Ich bin ein bisschen enttäuscht, das wusste ich nicht früher, also hoffe ich, dass das den Typ Lerche ein wenig für jemand anderen verdeutlicht! Und bedeutet viel weniger Casting als ich zuerst dachte :)
quelle
is := make(MySlice, 0); m := make(MyMap)
, was in einigen Kontexten besser lesbar ist.Sowohl die Frage als auch die Antwort sind ziemlich aufschlussreich. Ich möchte jedoch eine Unterscheidung treffen, die in der Antwort von Lytnus nicht klar ist.
Der benannte Typ unterscheidet sich vom unbenannten Typ .
Eine Variable vom benannten Typ kann einer Variablen vom unbenannten Typ zugewiesen werden , und umgekehrt.
Variablen unterschiedlichen benannten Typs können einander nicht zugewiesen werden.
http://play.golang.org/p/uaYHEnofT9
quelle