Ich habe eine Zeichenfolge, die eine Ganzzahl enthält (die aus einer Datei gelesen wurde).
Ich versuche das string
in ein int
using umzuwandeln strconv.ParseInt()
. ParseInt
erfordert, dass ich eine Bitgröße gebe (die Bitgrößen 0, 8, 16, 32 und 64 entsprechen int, int8, int16, int32 und int64).
Die aus der Datei gelesene Ganzzahl ist klein (dh sie sollte in ein normales int passen). Wenn ich jedoch eine Bitgröße von 0 übergebe, erhalte ich ein Ergebnis vom Typ int64
(vermutlich, weil ich auf einem 64-Bit-Betriebssystem arbeite).
Warum passiert das? Wie bekomme ich nur einen normalen int? (Wenn jemand eine kurze Einführung hat, wann und warum ich die verschiedenen int-Typen verwenden sollte, wäre das großartig!)
Bearbeiten: Ich kann den int64 mit in einen normalen int konvertieren int([i64_var])
. Aber ich verstehe immer noch nicht, warum ParseInt()
ich einen int64 bekomme, wenn ich eine Bitgröße von 0 anfordere.
parseInt(s, 0, 0)
, was auf base10 schließen sollte (da die Zeichenfolge kein Basispräfix hat). Atoi ist jedoch eine Abkürzung für den AufrufparseInt
mit einer Basis von 10. Warum unterscheidet der Basisparameter den zurückgegebenen Typ?0
bedeutet, dass der Code versucht, dies selbst herauszufinden. Aber manchmal ist das nicht möglich.11
(dezimal) vs11
(binär) repräsentieren völlig unterschiedliche Werte.parseInt(s, 10, 0)
" ist. Aber warum kehrt Atoi dann zurück,int
währendparseInt
int64 zurückkehrt?Atoi
int atoi ( const char * str );
Antworten:
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt kehrt immer zurück
int64
bitSize
definiert den Wertebereich. Wenn der Wert, der s entspricht, nicht durch eine vorzeichenbehaftete Ganzzahl der angegebenen Größe dargestellt werden kann, ist err.Err = ErrRange.http://golang.org/pkg/strconv/#ParseInt
type int int
int ist ein vorzeichenbehafteter Integer-Typ mit einer Größe von mindestens 32 Bit. Es ist jedoch ein bestimmter Typ und kein Alias für beispielsweise int32.
http://golang.org/pkg/builtin/#int
Könnte
int
also in Zukunft größer als 32 Bit sein oder auf einigen Systemen wieint
in C.Ich denke, auf einigen Systemen ist es
int64
möglicherweise schneller alsint32
weil dieses System nur mit 64-Bit-Ganzzahlen funktioniert.Hier ist ein Beispiel für einen Fehler, wenn
bitSize
8 isthttp://play.golang.org/p/_osjMqL6Nj
package main import ( "fmt" "strconv" ) func main() { i, err := strconv.ParseInt("123456", 10, 8) fmt.Println(i, err) }
quelle
int64
fürint
eine amd64-GOARCH undint32
für eineint
32-Bit-GOARCH verwendet. Zumindest mit dem Standard-Compiler bin ich mir bei gccgo nicht sicher. "int
Könnte größer als 32 Bit sein ..." ist also nicht nur Spekulation, sondern eher wahrscheinlich, da die 64-Bit-Kompilierungsziele im Allgemeinen als Hauptzweig in Go angesehen werden.ParseInt
gibt immer einenint64
Wert zurück. Je nachbitSize
wird dieser Wert paßt inint
,int8
,int16
,int32
, oderint64
. Wenn der Wert nicht durch eine vorzeichenbehaftete Ganzzahl der angegebenen Größe dargestellt werden kannbitSize
, dannerr.Err = ErrRange
.int
beträgt je nach Implementierung entweder 32 oder 64 Bit. Normalerweise sind es 32 Bit für 32-Bit-Compiler und 64 Bit für 64-Bit-Compiler.Um die Größe eines
int
oder herauszufindenuint
, verwenden Siestrconv.IntSize
.Zum Beispiel,
package main import ( "fmt" "runtime" "strconv" ) func main() { fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS) fmt.Println(strconv.IntSize) }
Ausgabe:
gc amd64 linux 64
quelle
strconv.ParseInt
und Freunde geben 64-Bit-Versionen zurück, um die API sauber und einfach zu halten. Andernfalls müssten für jeden möglichen Rückgabetyp separate Versionen erstellt werden. Oder kehren Sie zurückinterface{}
, was dann eine Typzusicherung durchlaufen müsste. Nichts davon ist ideal.int64
wird gewählt, weil es eine beliebige Ganzzahlgröße bis einschließlich der unterstützten 64-Bit enthalten kann. Die Bitgröße, die Sie an die Funktion übergeben, stellt sicher, dass der Wert ordnungsgemäß auf den richtigen Bereich geklemmt wird. Sie können also einfach eine Typkonvertierung für den zurückgegebenen Wert durchführen, um ihn in einen beliebigen Ganzzahltyp umzuwandeln.Der Unterschied zwischen
int
undint64
ist architekturabhängig.int
ist einfach ein Alias für eine 32-Bit- oder 64-Bit-Ganzzahl, abhängig von der Architektur, für die Sie kompilieren.Für das anspruchsvolle Auge: Der zurückgegebene Wert ist eine vorzeichenbehaftete Ganzzahl. Es gibt eine separate
strconv.ParseUint
Funktion für vorzeichenlose Ganzzahlen, dieuint64
dieselbe Argumentation wie oben erläutert zurückgibt und folgt.quelle
int
es einfach ein Alias ist - es ist in der Tat ein bestimmter Typ. golang.org/pkg/builtin/#inttype int int32
ist als einzigartiger und separater Typ zu behandeln. Insbesondere, weilint
durch die Anwendung neuer Methoden neue Funktionen für den Typ definiert werden können.Für Ihre Zwecke
strconv.Atoi()
wäre das bequemer, denke ich.Die anderen Antworten waren ziemlich ausführlich in
int
Bezug auf die Erklärung des Typs, aber ich denke, ein Link zur Go-Sprachspezifikation ist hier verdient: http://golang.org/ref/spec#Numeric_typesquelle
In Go lang wird jeder Typ als separater Datentyp betrachtet, der nicht austauschbar mit dem Basistyp verwendet werden kann. Zum Beispiel,
type CustomInt64 int64
In der obigen Deklaration sind CustomInt64 und integriertes int64 zwei separate Datentypen und können nicht austauschbar verwendet werden.
Das Gleiche gilt für int, int32 und int64. All dies sind separate Datentypen, die nicht austauschbar verwendet werden können. Wenn int32 32 sein ganzzahliger Typ ist, ist int64 64 Bit und die Größe des generischen int-Typs ist plattformabhängig. Sie ist auf einem 32-Bit-System 32 Bit breit und auf einem 64-Bit-System 64 Bit breit. Wir müssen also vorsichtig und spezifisch sein, wenn wir generische Datentypen wie int, uint und float angeben. Es kann irgendwo im Code ein Problem verursachen und die Anwendung auf einer anderen Plattform zum Absturz bringen.
quelle