Verweis auf string-Literale in Gehen
In meiner Anwendung, die ich Häufig passieren verweist auf einen statischen string. Ich möchte vermeiden, dass Sie Gehen, reservieren Sie Speicher für jeden Anruf, aber ich konnte, um die Adresse zu meinem string-literal.
Warum ist es nicht möglich, die Adresse einer string-literal (siehe test1()
im Beispiel unten)? Habe ich falsch verstanden, die syntax, oder ist es eine Beschränkung auf Grund der internen Funktionsweise Gehen?
Falls dies nicht möglich ist, was wäre die beste Lösung?
test2()
funktioniert, aber es wird Speicher für die var hej
jedes mal?
test3()
nicht zugeordnet werden keine neuen Speicher, aber ich wünschte, um Unordnung zu vermeiden, die außerhalb der Funktion.
package main
import "fmt"
var konnichiwa = `こんにちは世界`
//Gives the compile error `cannot take the address of "Hello world"`
func test1() (*string) { return &`Hello world` }
//Works fine
func test2() (*string) {
hej := `Hej världen`
return &hej
}
func test3() (*string) { return &konnichiwa }
func main(){
fmt.Println(*test1())
fmt.Println(*test2())
fmt.Println(*test3())
}
Danke für die Hilfe!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Unter der Adresse, der ein literal (Zeichenkette, Zahl, etc) ist illegal, weil es mehrdeutig Semantik.
Sind Sie unter der Adresse der eigentlichen konstant? Was würde es der Wert geändert werden (und könnte zu einem Laufzeit-Fehler) oder wollen Sie reservieren, ein neues Objekt, kopieren Sie die Konstante über die Adresse auf die neue version?
Diese Mehrdeutigkeit existiert nicht im Falle von
test2
da Sie es mit einer vorhandenen variable, die die Semantik eindeutig definiert sind. Das gleiche würde nicht funktionieren, wenn der string war definiert alsconst
.Die Sprache spec vermeidet diese Mehrdeutigkeit auf, indem Sie explizit nicht erlaubt, was Ihr bittet. Die Lösung ist
test2
. Es ist zwar etwas Ausführlicher, es hält die Regeln einfach und sauber.Natürlich, jede Regel hat Ihre Ausnahmen, und im Gehen, dies betrifft Komposit-Literale: Das folgende ist legal und im Sinne des spec:
Für die Frage nach der besten Lösung für Ihre situation vorbei "static" - Saiten,
Es ist verlockend zu geben, die Ratschläge "Mach dir keine sorgen über die Zuweisung von strings", weil das tatsächlich wahr ist, im Falle Sie beschreiben, wo die gleiche Zeichenfolge übergeben herum, vielleicht viele Male. Es Allgemeinen jedoch, es ist wirklich gut zu denken über die Verwendung des Speichers. Es ist wirklich einfach nur schlecht, zu erraten, und noch schlimmer, zu erraten, basierend auf den Erfahrungen mit einer anderen Sprache.
Hier ist eine modifizierte version des Programms. Wo tun Sie erraten, dass Speicher reserviert?
Nun fragt sich der compiler:
(Ich nannte das Programm t.gehen.) Suche die Ausgabe der Aufrufe zur Laufzeit.neue. Es gibt nur eine! Ich werde verderben es für Sie, es ist in test1.
Also ohne off zu viel von einer Tangente, die kleiner Blick auf die compiler-Ausgabe zeigt, dass wir vermeiden, Zuweisung durch das arbeiten mit den string-Typ statt *string.
go tool
zu Holen Sie sich die Montage selbst. Verflucht, jetzt werde ich sitzen, zu analysieren Gehen Sie assembly-code für stundenlangen Spaß. Danke! (Und ja, ich werde stick mit Ihren Lösungen)go tool: no such tool "6g"
mit gehen 1.10, aber das funktionierte:go tool compile -S t.go
Einen string in gehen unveränderlich ist und nur einen Zeiger und eine Länge (Gesamt Länge : 2 Wörter).
So dass Sie nicht haben, um zu verwenden, einen Zeiger zu handhaben, effizient.
Nur die Zeichenfolge übergeben.
Weitergabe um eine Zeichenfolge nicht in der Regel Speicher im Gehen - es ist ein Wert-Typ (ptr, um die Byte-und int len).
Einnahme eine Adresse von ein literal wird nur unterstützt für composite-Literale wie
v := &T{1, "foo"}
aber nicht für einfache Werte, wie
w := &1
x := &"foo"