Menu

Golang int zu string, string zu int und Typkonvertierung

So konvertierst du in Go zwischen Typen: int zu string und string zu int mit strconv, Floats zu Ganzzahlen, numerische Konvertierungen mit T(v), Bytes und Runes, die Falle string(65) und der Umgang mit Konvertierungsfehlern.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Go konvertiert Typen nie implizit. Zwischen kompatiblen Typen konvertierst du mit T(v), zwischen Zahlen und Text mit dem Paket strconv. Die beiden meistgesuchten Konvertierungen:

strconv.Itoa („integer to ASCII“) formatiert ein int als Dezimaltext. strconv.Atoi („ASCII to integer“) parst Text in ein int und gibt einen Fehler zurück, wenn der Text keine gültige Zahl ist. Prüf diesen Fehler immer.

Die Konvertierung T(v)

Die Syntax für Konvertierungen in Go sieht aus wie ein Funktionsaufruf, benannt nach dem Zieltyp. Sie funktioniert in drei Situationen:

  1. zwischen numerischen Typen (int, int64, float64, uint8, ...),
  2. zwischen string und []byte oder []rune,
  3. zwischen Typen, die sich einen zugrunde liegenden Typ teilen (Celsius und float64).

Sieh dir die Ergebnisse genau an:

  • int(3.9) ist 3 und int(-3.9) ist -3. Die Konvertierung schneidet in Richtung null ab; sie rundet nicht. Nimm vorher math.Round, math.Floor oder math.Ceil, um das Verhalten zu wählen. math.Round rundet bei ,5 von null weg, also wird -3.5 zu -4.
  • uint8(300) ist 44, weil nur die unteren 8 Bit übrig bleiben (300 minus 256), und int8(200) ist aus demselben Grund -56. Kein Fehler, keine Panic.
  • Celsius und float64 teilen sich einen zugrunde liegenden Typ, also lassen sie sich frei konvertieren, aber nur explizit.

Die Werte stehen absichtlich in Variablen. Mit Konstanten kompilieren dieselben Konvertierungen nicht.

Konstanten werden geprüft, Variablen nicht

Eine Konstante zu konvertieren, die nicht passt, ist ein Compilerfehler. Eine Variable mit demselben Wert zu konvertieren läuft still über:

fmt.Println(uint8(300)) // compile error
x := 300
fmt.Println(uint8(x)) // 44
./main.go:6:20: constant 300 overflows uint8

Auch eine nicht ganzzahlige Konstante in einen Ganzzahltyp zu konvertieren wird abgelehnt, während derselbe Wert in einer Variablen abgeschnitten wird:

./main.go:7:18: cannot convert -3.9 (untyped float constant) to type int

Liegt der Float-Wert außerhalb des Bereichs des Ganzzahl-Zieltyps (etwa int64(1e20)), ist das Ergebnis implementierungsabhängig: amd64 und arm64 liefern zum Beispiel verschiedene Antworten. Prüf den Bereich, bevor du nicht vertrauenswürdige Werte konvertierst.

Zahlen in Strings konvertieren

VonFunktionBeispielErgebnis
intstrconv.Itoa(n)strconv.Itoa(-7)"-7"
int64strconv.FormatInt(n, base)strconv.FormatInt(255, 16)"ff"
uint64strconv.FormatUint(n, base)strconv.FormatUint(5, 2)"101"
float64strconv.FormatFloat(f, fmt, prec, 64)strconv.FormatFloat(3.14159, 'f', 2, 64)"3.14"
boolstrconv.FormatBool(b)strconv.FormatBool(true)"true"
beliebigfmt.Sprint(v)fmt.Sprint(3.5)"3.5"
beliebig, formatiertfmt.Sprintf(format, v)fmt.Sprintf("%05d", 42)"00042"

FormatFloat nimmt ein Format-Byte ('f' für Festkomma, 'e' für Exponent, 'g' für die kürzere Variante), eine Genauigkeit (-1 bedeutet „die wenigsten Ziffern, die sich exakt zurückverwandeln lassen“) und die Bitgröße des ursprünglichen Floats (64 oder 32).

strconv ist schneller als fmt.Sprint, das den Wert in ein Interface packt und den allgemeinen Formatierungspfad von fmt durchläuft. In einer heißen Schleife macht sich das bemerkbar; bei gelegentlichen Konvertierungen nimm, was sich besser liest.

Strings in Zahlen konvertieren

NachFunktionGibt zurück
intstrconv.Atoi(s)int, error
jeder vorzeichenbehaftete intstrconv.ParseInt(s, base, bitSize)int64, error
jeder vorzeichenlose intstrconv.ParseUint(s, base, bitSize)uint64, error
floatstrconv.ParseFloat(s, bitSize)float64, error
boolstrconv.ParseBool(s)bool, error

ParseInt gibt immer ein int64 zurück. Das Argument bitSize (0, 8, 16, 32, 64) legt den akzeptierten Bereich fest, also passt das Ergebnis garantiert, wenn du es herunterkonvertierst. base 0 bedeutet „aus dem Präfix ableiten“, also werden 0x1f, 0o17, 0b101 und 1_000 alle geparst.

Was die Ausgabe zeigt:

  • " 42" scheitert. Atoi akzeptiert ein optionales Vorzeichen und Ziffern, sonst nichts. Eingaben aus bufio enden meist mit \n, also kürze sie vorher.
  • "4.2" ist für Atoi ungültig. Für Dezimalzahlen nimm ParseFloat.
  • Bei einem Bereichsfehler gibt ParseInt den größten passenden Wert (127 für int8) zusammen mit dem Fehler zurück. Verwende den Wert nicht, wenn der Fehler nicht nil ist.
  • Die Fehler sind *strconv.NumError-Werte, die strconv.ErrSyntax oder strconv.ErrRange wrappen, also kann errors.Is sie unterscheiden.

ParseBool akzeptiert 1, t, T, TRUE, true, True und die entsprechenden Formen für false. "yes" und "on" sind Fehler.

Die Falle string(65)

Eine Ganzzahl in string zu konvertieren erzeugt keine Ziffern. Es erzeugt das Zeichen mit diesem Unicode-Codepoint:

n := 65
s := string(n) // "A", not "65"

Der Compiler akzeptiert das, aber go vet meldet es:

./main.go:10:7: conversion from int to string yields a string of one rune, not a string of digits

Willst du wirklich das Zeichen, sag es mit einer Rune: string(rune(n)). Willst du die Zahl als Text, nimm strconv.Itoa(n). Eine rune oder ein byte in string zu konvertieren ist in Ordnung und verbreitet:

Strings, Bytes und Runes

string, []byte und []rune lassen sich mit T(v) ineinander konvertieren. Jede Konvertierung kopiert die Daten, weil Strings unveränderlich sind und Slices nicht:

Konvertiere in []rune, wenn du zeichenweise indizieren oder ändern musst; konvertiere in []byte für I/O, Hashing und Änderungen auf Byte-Ebene. Die Seite zu Runes und Bytes erklärt UTF-8 im Detail.

Konvertierung vs Type Assertion

Eine Konvertierung macht aus einem Wert eines konkreten Typs einen anderen. Den konkreten Wert aus einem Interface (any, error, io.Reader) zu holen ist eine andere Operation, die Type Assertion:

var v any = 42

n := v.(int)       // type assertion: v holds an int, give it to me
f := float64(n)    // conversion: int to float64
// f := float64(v) // compile error: cannot convert v (variable of interface type any)
//                  // to type float64: need type assertion

Erst die Assertion, dann die Konvertierung. Die Comma-ok-Form n, ok := v.(int) vermeidet eine Panic, wenn der Typ falsch ist.

Kurzreferenz

AufgabeCode
int zu stringstrconv.Itoa(n)
int64 zu stringstrconv.FormatInt(n, 10)
string zu intn, err := strconv.Atoi(s)
string zu int64n, err := strconv.ParseInt(s, 10, 64)
string zu float64f, err := strconv.ParseFloat(s, 64)
float64 zu stringstrconv.FormatFloat(f, 'f', -1, 64)
float64 zu intint(f) (schneidet ab) oder int(math.Round(f))
int zu float64float64(n)
string zu []byte[]byte(s)
[]byte zu stringstring(b)
rune zu stringstring(r)
bool zu stringstrconv.FormatBool(b)
beliebiger Wert zu stringfmt.Sprint(v)

Häufig gestellte Fragen

Wie konvertiere ich in Go ein int in einen String?

Mit strconv.Itoa(n): strconv.Itoa(42) gibt "42" zurück. Für ein int64 nimm strconv.FormatInt(n, 10). fmt.Sprint(n) funktioniert auch, für jeden Typ, ist aber langsamer. Schreib nicht string(n): Das behandelt n als Unicode-Codepoint, also ist string(65) gleich "A".

Wie konvertiere ich in Go einen String in ein int?

Mit strconv.Atoi, das die Zahl und einen Fehler zurückgibt:

n, err := strconv.Atoi("42")
if err != nil {
	// not a valid integer
}

Für eine bestimmte Größe oder Basis nimm strconv.ParseInt(s, 10, 64), das ein int64 zurückgibt. Atoi entfernt keine Leerzeichen, also ist " 42" ein Fehler; ruf vorher strings.TrimSpace auf.

Wie castet man in Go?

Go nennt es Konvertierung, und die Syntax ist T(v): float64(n), int(f), []byte(s). Sie funktioniert zwischen numerischen Typen, zwischen Strings und Byte- oder Rune-Slices und zwischen Typen mit demselben zugrunde liegenden Typ. Text parst sie nicht: Um aus "42" eine 42 zu machen, brauchst du strconv. Einen konkreten Typ aus einem Interface zu holen ist eine Type Assertion, v.(T), keine Konvertierung.

Wie konvertiere ich in Go einen Float in ein int?

int(f) schneidet in Richtung null ab: int(3.9) ist 3 und int(-3.9) ist -3. Zum Runden nimm int(math.Round(f)). Liegt der Float außerhalb des Bereichs des Ganzzahltyps, ist das Ergebnis implementierungsabhängig, also prüf den Bereich vorher, wenn der Wert aus einer Eingabe stammt.

Warum gibt string(65) in Go „A“ zurück?

Die Konvertierung einer Ganzzahl in string interpretiert sie als Unicode-Codepoint, und 65 ist der Codepoint von A. go vet meldet das: conversion from int to string yields a string of one rune, not a string of digits. Nimm strconv.Itoa(65), um "65" zu bekommen.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S