Grundlagen von Go-Strings

GolangGolangBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In der vorherigen Lektion haben wir gelernt, dass Zeichen in Go mit UTF-8 codiert und entweder als byte oder rune Typen gespeichert werden. Jetzt wollen wir uns Strings (Zeichenketten) anschauen, die Sammlungen von Zeichen sind. Lassen Sie uns dieses Thema gemeinsam erkunden.

Wissenspunkte:

  • Was ist ein String
  • Erstellen eines Strings
  • Deklarieren eines Strings
  • Häufige String-Funktionen
  • Zugriff auf String-Elemente

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/BasicsGroup(["Basics"]) go(("Golang")) -.-> go/DataTypesandStructuresGroup(["Data Types and Structures"]) go(("Golang")) -.-> go/FunctionsandControlFlowGroup(["Functions and Control Flow"]) go(("Golang")) -.-> go/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) go(("Golang")) -.-> go/AdvancedTopicsGroup(["Advanced Topics"]) go/BasicsGroup -.-> go/values("Values") go/BasicsGroup -.-> go/variables("Variables") go/DataTypesandStructuresGroup -.-> go/strings("Strings") go/FunctionsandControlFlowGroup -.-> go/for("For") go/FunctionsandControlFlowGroup -.-> go/functions("Functions") go/ObjectOrientedProgrammingGroup -.-> go/struct_embedding("Struct Embedding") go/AdvancedTopicsGroup -.-> go/text_templates("Text Templates") go/AdvancedTopicsGroup -.-> go/number_parsing("Number Parsing") subgraph Lab Skills go/values -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/variables -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/strings -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/for -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/functions -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/struct_embedding -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/text_templates -.-> lab-149069{{"Grundlagen von Go-Strings"}} go/number_parsing -.-> lab-149069{{"Grundlagen von Go-Strings"}} end

Was ist ein String?

In unserem ersten Go-Programm haben wir die Zeichenkette "hello, world" ausgegeben.

Ein String ist ein grundlegender Datentyp in Go, auch als String-Literal (Zeichenkettenliteral) bekannt. Man kann ihn als Sammlung von Zeichen verstehen, die einen zusammenhängenden Speicherblock belegt. Dieser Speicherblock kann beliebige Datentypen speichern, wie Buchstaben, Text, Emojis usw.

Im Gegensatz zu anderen Programmiersprachen sind Strings in Go unveränderlich (immutable) und können nicht modifiziert werden. Das bedeutet, dass Sie nach der Erstellung eines Strings seine einzelnen Zeichen nicht ändern können. Wenn Sie eine modifizierte Version eines Strings benötigen, müssen Sie einen neuen erstellen.

Erstellen eines Strings

Strings können auf verschiedene Arten deklariert werden. Schauen wir uns zunächst die erste Methode an. Erstellen Sie eine neue Datei namens string.go:

touch ~/project/string.go

Schreiben Sie den folgenden Code:

package main

import "fmt"

func main() {
    // Use the var keyword to create a string variable a
    var a string = "labex"
    a = "labex" // Assign "labex" to variable a

    // Declare variable b and assign its value
    var b string = "labs"

    // Type declaration can be omitted
    var c = "Monday"

    // Use := for quick declaration and assignment
    d := "Sunday"
    fmt.Println(a, b, c, d)
}

Der obige Code zeigt, wie man Strings mit dem var-Schlüsselwort und dem :=-Operator erstellt. Wenn Sie einen Wert zuweisen, wenn Sie eine Variable mit var erstellen, können Sie die Typdeklaration weglassen, wie bei der Erstellung der Variable c gezeigt. Der :=-Operator ist eine Abkürzung für die Deklaration und Initialisierung einer Variable in Go. Er leitet automatisch den Typ der Variable aus dem zugewiesenen Wert ab. Seine Verwendung macht Ihren Code kompakter.

go run string.go

Die erwartete Ausgabe ist wie folgt:

labex labs Monday Sunday

Deklarieren eines Strings

In den meisten Fällen verwenden wir doppelte Anführungszeichen "", um Strings zu deklarieren. Der Vorteil von doppelten Anführungszeichen besteht darin, dass sie für Escapesequenzen verwendet werden können. Beispielsweise verwenden wir in folgendem Programm die Escapesequenz \n, um eine neue Zeile zu erstellen:

package main

import "fmt"

func main() {
    x := "linux\nlabex"
    fmt.Println(x)
}
go run string.go

Die erwartete Ausgabe ist wie folgt:

linux
labex

Hier sind einige häufige Escapesequenzen:

Symbol Beschreibung
\n Neue Zeile
\r Wagenrücklauf
\t Tabulator
\b Rückschritt
\\ Backslash
\' Einzelnes Anführungszeichen
\" Doppeltes Anführungszeichen

Wenn Sie das ursprüngliche Format des Textes beibehalten möchten oder mehrere Zeilen verwenden müssen, können Sie Backticks (`) verwenden:

package main

import "fmt"

func main() {
    // Output the ASCII art of "labex"
    ascii := `
        ##        #####   #########  ########## ##    #
        ##       ##  ##  ##    ## ##       ##  #
        ##      ##    ## #########  #########    ##
        ##      ########## ##    ## ##        ##
        ##      ##    ## ##    ## ##       ##  #
        ########## ##    ## #########  ########## ##    #`
    fmt.Println(ascii)
}

Backticks werden häufig in Prompts, HTML-Templates und anderen Fällen verwendet, in denen das ursprüngliche Format der Ausgabe beibehalten werden muss. Der Text innerhalb der Backticks wird als rohes String-Literal (raw string literal) behandelt, was bedeutet, dass Escapesequenzen nicht interpretiert werden. Dies erleichtert es, mehrzeiligen Text und Sonderzeichen einzufügen, ohne sie escapen zu müssen.

Ermitteln der Länge eines Strings

In der vorherigen Lektion haben wir gelernt, dass englische Zeichen und allgemeine Satzzeichen ein Byte belegen.

Daher können wir in Go die len()-Funktion verwenden, um die Byte-Länge eines Strings zu ermitteln. Wenn keine Zeichen enthalten sind, die mehrere Bytes belegen, kann die len()-Funktion verwendet werden, um die Länge des Strings genau zu messen.

Enthält ein String Zeichen, die mehrere Bytes belegen, können Sie die utf8.RuneCountInString-Funktion verwenden, um die tatsächliche Anzahl der Zeichen im String zu erhalten.

Schauen wir uns ein Beispiel an. Schreiben Sie den folgenden Code in die Datei string.go:

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    // Declare two empty strings using var and :=
    var a string
    b := ""

    c := "labex"
    d := "abc"


    // Output byte length
    fmt.Printf("The value of a is %s, the byte length of a is: %d\n", a, len(a))
    fmt.Printf("The value of b is %s, the byte length of b is: %d\n", b, len(b))
    fmt.Printf("The value of c is %s, the byte length of c is: %d\n", c, len(c))
	fmt.Printf("The value of d is %s, the byte length of d is: %d\n", d, len(d))


    // Output string length
    fmt.Printf("The length of c is: %d\n", utf8.RuneCountInString(c))
	fmt.Printf("The length of d is: %d\n", utf8.RuneCountInString(d))
}
go run string.go

Die erwartete Ausgabe ist wie folgt:

The value of a is, the byte length of a is: 0
The value of b is, the byte length of b is: 0
The value of c is labex, the byte length of c is: 5
The value of d is abc, the byte length of d is: 3
The length of c is: 5
The length of d is: 3

In diesem Programm haben wir zunächst zwei leere Strings sowie die Strings labex und abc deklariert. Sie können sehen, dass ihre Byte-Längen und tatsächlichen Längen gleich sind, da sie nur ein-Byte-Zeichen enthalten.

Zugriff auf String-Elemente

Da Strings im Wesentlichen Sequenzen von Bytes sind, können wir einzelne Bytes oder Zeichen in einem String über ihren Index zugreifen. In Go beginnt die String-Indizierung wie bei Arrays bei 0.

Es ist jedoch wichtig zu beachten, dass der Zugriff auf String-Elemente über den Index ein byte und nicht ein Zeichen (rune) zurückgibt. Wenn der String mehr-Byte-Zeichen enthält, müssen Sie bei der Verwendung von Indizes vorsichtig sein, da Sie möglicherweise nicht das gesamte Zeichen erhalten. Um einzelne Zeichen (rune) sicher zu erhalten, können Sie den String mit einer for...range-Schleife durchlaufen, die die UTF-8-Kodierung richtig behandelt.

Fügen wir den folgenden Code zur Datei string.go hinzu:

package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {
	str := "Hello, world!"

	// Accessing byte by index
	fmt.Printf("Byte at index 0: %c\n", str[0]) // Output: H
	fmt.Printf("Byte at index 7: %c\n", str[7]) // Output: w

    // Iterate using for...range to safely get runes
    fmt.Println("Iterating through runes:")
    for index, char := range str {
        fmt.Printf("Index: %d, Char: %c\n", index, char)
    }

	// Getting the number of runes
	fmt.Printf("Number of runes (characters) in the string: %d\n", utf8.RuneCountInString(str))

}

Führen Sie jetzt das Programm aus:

go run string.go

Die Ausgabe ist:

Byte at index 0: H
Byte at index 7: w
Iterating through runes:
Index: 0, Char: H
Index: 1, Char: e
Index: 2, Char: l
Index: 3, Char: l
Index: 4, Char: o
Index: 5, Char:,
Index: 6, Char:
Index: 7, Char: w
Index: 8, Char: o
Index: 9, Char: r
Index: 10, Char: l
Index: 11, Char: d
Index: 12, Char:!
Number of runes (characters) in the string: 13

In dieser Ausgabe können Sie sehen, dass:

  1. Der Zugriff auf einen String über einen bestimmten Index gibt ein Byte zurück.
  2. Die Verwendung einer for...range-Schleife ermöglicht es Ihnen, die rune-Zeichen korrekt zu durchlaufen.

Dieses Beispiel zeigt den wichtigen Unterschied zwischen byte und rune und die Wichtigkeit der Verwendung der geeigneten Methoden bei der Verarbeitung von Zeichen in Go-Strings.

Konvertieren von Strings und Ganzzahlen

Wir können Funktionen aus dem strconv-Paket verwenden, um zwischen Strings und Ganzzahlen zu konvertieren:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    // Declare a string a and an integer b
    a, b := "233", 223

    // Use Atoi to convert a string to an integer
    c, _ := strconv.Atoi(a)

    // Use Sprintf and Itoa functions respectively
    // to convert an integer to a string
    d1 := fmt.Sprintf("%d", b)
    d2 := strconv.Itoa(b)

    fmt.Printf("The type of a: %T\n", a)   // string
    fmt.Printf("The type of b: %T\n", b)   // int
    fmt.Printf("The type of c: %T\n", c)   // int
    fmt.Printf("The type of d1: %T\n", d1) // string
    fmt.Printf("The type of d2: %T\n", d2) // string
}
go run string.go

Die erwartete Ausgabe ist wie folgt:

The type of a: string
The type of b: int
The type of c: int
The type of d1: string
The type of d2: string

In diesem Programm verwenden wir die Sprintf()-Funktion aus dem fmt-Paket, die folgendes Format hat:

func Sprintf(format string, a...interface{}) string

format ist ein String mit Escapesequenzen, a ist eine Konstante oder Variable, die Werte für die Escapesequenzen bereitstellt, und ... bedeutet, dass es mehrere Variablen des gleichen Typs wie a geben kann. Der String hinter der Funktion gibt an, dass Sprintf einen String zurückgibt. Hier ist ein Beispiel für die Verwendung dieser Funktion:

a = fmt.Sprintf("%d+%d=%d", 1, 2, 3)
fmt.Println(a) // 1+2=3

In diesem Codeausschnitt werden der format-Funktion drei Ganzzahlvariablen 1, 2 und 3 übergeben. Das Ganzzahl-Escapeteichen %d in format wird durch die Ganzzahlwerte ersetzt, und die Sprintf-Funktion gibt das Ergebnis nach der Ersetzung, 1+2=3, zurück.

Beachten Sie auch, dass die strconv.Atoi()-Funktion beim Konvertieren eines Strings in eine Ganzzahl zwei Werte zurückgibt: die konvertierte Ganzzahl val und den Fehlercode err. Da in Go jede deklarierte Variable verwendet werden muss, können wir einen Unterstrich _ verwenden, um die err-Variable zu ignorieren.

Wenn strconv.Atoi() korrekt konvertiert, gibt err nil zurück. Tritt während der Konvertierung ein Fehler auf, gibt err die Fehlermeldung zurück, und der Wert von val wird 0 sein. Sie können den Wert des Strings a ändern und den Unterstrich durch eine normale Variable ersetzen, um es selbst auszuprobieren. Dies ist eine gute Übung für die Fehlerbehandlung, die ein wichtiger Bestandteil der Go-Programmierung ist.

Verkettung von Strings

Die einfachste Methode, um zwei oder mehr Strings zu verketten, ist die Verwendung des +-Operators. Wir können auch die fmt.Sprintf()-Funktion nutzen, um Strings zu verketten. Schauen wir uns ein Beispiel an:

package main

import (
    "fmt"
)

func main() {
    a, b := "lab", "ex"
    // Concatenate using the simplest method, +
    c1 := a + b
    // Concatenate using the Sprintf function
    c2 := fmt.Sprintf("%s%s", a, b)
    fmt.Println(a, b, c1, c2) // lab ex labex labex
}
go run string.go

Die erwartete Ausgabe ist wie folgt:

lab ex labex labex

In diesem Programm haben wir auch die Sprintf()-Funktion aus dem fmt-Paket verwendet, um Strings zu verketten und die Ergebnisse auszugeben. Beide Methoden sind gängige Wege, Strings zu verketten, und die Wahl zwischen ihnen hängt oft von der Lesbarkeit und persönlichen Präferenz ab.

Entfernen von führenden und nachfolgenden Leerzeichen aus einem String

Wir können die strings.TrimSpace-Funktion verwenden, um führende und nachfolgende Leerzeichen aus einem String zu entfernen. Die Funktion nimmt einen String als Eingabe und gibt den String ohne führende und nachfolgende Leerzeichen zurück. Das Format ist wie folgt:

func TrimSpace(s string) string

Hier ist ein Beispiel:

package main

import (
    "fmt"
    "strings"
)

func main() {
    a := " \t \n  labex \n \t labs"
    fmt.Println(strings.TrimSpace(a))
}
go run string.go

Die erwartete Ausgabe ist wie folgt:

labex
         labs

Beachten Sie, dass strings.TrimSpace() nur Leerzeichen am Anfang und am Ende des Strings entfernt. Leerzeichen innerhalb des Strings bleiben unverändert.

Zusammenfassung

Um zusammenzufassen, was wir in dieser Lektion gelernt haben:

  • Die Beziehung zwischen Strings und Zeichen
  • Zwei Methoden zur Deklaration von Strings: die Verwendung von doppelten Anführungszeichen und Backticks.
  • Zugriff auf Elemente eines Strings über den Index (Byte-Zugriff) und for...range (Rune-Zugriff).
  • Ermittlung der Länge eines Strings mit len() (Byte-Länge) und utf8.RuneCountInString (Zeichen/Rune-Länge).
  • Konvertierung von Strings und Ganzzahlen mit strconv.Atoi() und strconv.Itoa().
  • Verkettung von Strings mit dem +-Operator und fmt.Sprintf().
  • Entfernung von führenden und nachfolgenden Leerzeichen aus einem String mit strings.TrimSpace().

In dieser Lektion haben wir die Strings erklärt, die wir im täglichen Leben verwenden. Wir haben die Beziehung zwischen Strings und Zeichen kennengelernt, die Erstellung und Deklaration von Strings beherrscht und einige Kenntnisse über gängige String-Funktionen erworben. Wir haben auch gelernt, wie man sicher auf einzelne Zeichen in einem String zugreift, insbesondere wenn es um mehr-Byte-Zeichen geht, und verstehen nun einige wichtige Methoden zur String-Manipulation. Dies gibt Ihnen eine solide Grundlage für die Arbeit mit String-Daten in Go.