Dieser Artikel wurde von der Kolumne golang-Tutorial geschrieben, um Sie in das Problem der Zeichenfolgentypänderung in Golang einzuführen. Sie fragen sich möglicherweise, dass es für uns normal ist, Zeichenfolgen in Go zu ändern ? Können Sie keine Änderungen vornehmen? Das Folgende wird anhand von Beispielen ausführlich erläutert. Ich hoffe, dass es Freunden in Not hilfreich sein wird!
Wenn man mit einer Sprache wie Go in Kontakt kommt, hört man diesen Satz vielleicht oft. Sie fragen sich vielleicht, dass Strings in der täglichen Entwicklung nicht geändert werden können. Warum sagen wir, dass Strings in Go nicht geändert werden können?
Dieser Artikel zeigt Ihnen anhand eines praktischen Falls, warum Zeichenfolgen in Go nicht geändert werden können.
Bevor wir dieses Problem demonstrieren, lassen Sie uns zunächst eine grobe Demonstration des Grundwissens über String-Typen geben, damit jeder das Problem besser verstehen kann.
String ist ein Datentyp, der zur Darstellung von Zeichen verwendet wird. Verwenden Sie bei der Verwendung „ “, um den Zeicheninhalt einzuschließen. Zum Beispiel die folgende Form:
package main import "fmt" func main() { var str string = "Hello World!" }
In Go werden Zeichenfolgen normalerweise auf drei Arten definiert:
// 第一种(全量定义) var 变量名称 string = "字符串内容" // 类型推导 var 变量名称 = "字符串内容" // 短标记(只适用于局部变量) 变量名称 := "字符串内容"
Die Definition von Zeichenfolgen kann tatsächlich in Bytes erfolgen. Die hier aufgeführten Methoden sind die gebräuchlichsten.
Strings in Go entsprechen dem Unicode-Standard und sind in UTF-8 codiert. Die unterste Schicht der Zeichenfolge besteht tatsächlich aus Bytes (wird später ausführlich erläutert). Verwenden Sie das folgende Beispiel, um den spezifischen Byte-Inhalt auszudrucken und anzuzeigen:
s := "Hello World!" for _, v := range s { fmt.Print(v) fmt.Print("\t") } // 72 101 108 108 111 32 87 111 114 108 100 33
Der vom obigen Code gedruckte Inhalt ist der Bytecode, der durch jedes Zeichen dargestellt wird.
Durch die obige grobe Demonstration haben wir ein grundlegendes Verständnis von Strings erlangt. Was Zeichenfolgen betrifft, die nicht geändert werden können, fragen Sie sich möglicherweise: Es ist normal, dass wir Zeichenfolgen in der täglichen Entwicklung neu zuweisen.
Tatsächlich möchte ich diese Aussage hier korrigieren. Die in der Entwicklung häufig verwendete Methode ist eigentlich ein Konzept der Neuzuweisung.
str := "Hello World!" // 重新赋值 str = "Hello Go!" // 字符串修改 str[0] = "I"
Das häufig gehörte Sprichwort, dass es nicht geändert werden kann, bezieht sich tatsächlich auf die zweite Möglichkeit des obigen Codes. Und wenn es auf diese Weise geändert wird, wird ein Fehler gemeldet: :kann nicht zu s [0] (Wert vom Typ Byte) zugewiesen werden
Zurück zum Thema: Warum können Zeichenfolgen in Go nicht durch Subskription geändert werden?
Das liegt daran, dass die String-Datenstruktur in Go eine Struktur ist, die aus einem Zeiger und einer Länge besteht. Das Slice, auf das der Zeiger zeigt, ist der tatsächliche String-Wert. Der Quellcode in Go hat eine solche Definition:
type stringStruct struct { str unsafe.Pointer // 指向一个byte类型的切片指针 len int // 字符串的长度 }
Dies liegt genau daran, dass die unterste Ebene ein Segment vom Bytetyp [] ist. Wenn wir Indizes verwenden, um den Wert zu ändern, weisen wir dem Bytetyp einen Zeicheninhalt zu muss Nicht erlaubt sein. Wir können jedoch durch Subskription auf den entsprechenden Bytewert zugreifen.
fmt.Println(s[0]) // output:72
Was sollen wir also tun, wenn wir den Wert durch Abonnements ändern möchten? Zu diesem Zeitpunkt müssen Sie es durch Slicing definieren und dann in eine Zeichenfolge konvertieren.
package main import ( "fmt" ) func main() { s1 := []byte{72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33} fmt.Println(string(s1)) // 将"H"修改为l s1[0] = 108 fmt.Println(string(s1)) } // output: Hello World! lello World!
Oben wird analysiert, warum Zeichenfolgen nicht mithilfe von Indizes zugewiesen werden können. Gehen wir zurück und erklären wir die Zuweisungsmethoden in der täglichen Entwicklung.
package main import ( "fmt" ) func main() { // 声明一个字符串,并给与初始值 s := "Hello World!" // 对变量 s 进行重新赋值 s := "Hello Go!" }
Warum können dann in diesem Szenario Zeichenfolgenwerte neu zugewiesen werden?
Das liegt daran, dass am Ende von Go tatsächlich ein Slice vom Typ [] Byte {} neu erstellt wird, das den Zeiger in der Variablen s auf die neue Speicherplatzadresse zeigt (das heißt hier Hallo Go!). Der ursprüngliche Hello World!-Speicherplatz wird mit dem Garbage-Collection-Mechanismus zurückgewonnen.
Vielleicht wird jeder darüber nachdenken, warum ein gewöhnlicher String so kompliziert zu entwerfen ist und Zeiger verwenden muss. Ich habe derzeit keine offizielle Dokumentation gefunden.
Meine persönliche Vermutung ist, dass die Zeichenfolge bei sehr langen Zeichen sehr leicht ist und problemlos übertragen werden kann, ohne sich Gedanken über das Kopieren aus dem Speicher machen zu müssen. Obwohl in Go die Parameterübergabe unabhängig davon erfolgt, ob es sich um einen Referenztyp oder einen Werttyp handelt, erfolgt die Übergabe als Wert. Aber Zeiger sind offensichtlich speichereffizienter als die Wertübergabe.
Das obige ist der detaillierte Inhalt vonWarum kann der Golang-String-Typ nicht geändert werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!