Mam ciąg zawierający liczbę całkowitą (która została odczytana z pliku).
Próbuję przekonwertować string
plik int
using strconv.ParseInt()
. ParseInt
wymaga podania rozmiaru bitu (rozmiary bitów 0, 8, 16, 32 i 64 odpowiadają int, int8, int16, int32 i int64).
Odczytana z pliku liczba całkowita jest mała (tzn. Powinna mieścić się w normalnej liczbie całkowitej). Jeśli jednak przekażę rozmiar bitu równy 0, otrzymam wynik typu int64
(prawdopodobnie dlatego, że pracuję na 64-bitowym systemie operacyjnym).
Dlaczego to się dzieje? Jak uzyskać normalne int? (Jeśli ktoś ma krótkie wprowadzenie na temat tego, kiedy i dlaczego powinienem używać różnych typów int, byłoby to niesamowite!)
Edycja: mogę przekonwertować int64 na normalny int używając int([i64_var])
. Ale nadal nie rozumiem, dlaczego ParseInt()
podaje mi int64, gdy żądam rozmiaru bitu 0.
parseInt(s, 0, 0)
, która powinna wnioskować Base10 (ponieważ łańcuch nie posiada prefiksu bazowej). Jednak Atoi jest skrótem do wywoływaniaparseInt
z liczbą 10. Dlaczego parametr bazowy ma wpływ na zwracany typ?0
oznacza, że kod próbuje sam to rozgryźć. Ale czasami nie jest to możliwe.11
(dziesiętne) vs11
(binarne) reprezentują zupełnie inne wartości.parseInt(s, 10, 0)
”. Ale dlaczego w takim razie Atoi wraca,int
aparseInt
zwraca int64?Atoi
zostało to dodane tylko po to, aby pomieścić ludzi, którzy są bardziej zaznajomieni z C API:int atoi ( const char * str );
Odpowiedzi:
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt zawsze zwraca
int64
bitSize
określa zakres wartości. Jeśli wartość odpowiadająca s nie może być reprezentowana przez liczbę całkowitą ze znakiem danego rozmiaru, err.Err = ErrRange.http://golang.org/pkg/strconv/#ParseInt
type int int
int to liczba całkowita ze znakiem o rozmiarze co najmniej 32 bitów. Jest to jednak odrębny typ, a nie alias, powiedzmy, int32.
http://golang.org/pkg/builtin/#int
Więc
int
może być większy niż 32-bitowy w przyszłości lub w niektórych systemach, takich jakint
C.Myślę, że w niektórych systemach
int64
może być szybszy niżint32
dlatego, że ten system działa tylko z 64-bitowymi liczbami całkowitymi.Oto przykład błędu, gdy
bitSize
wynosi 8http://play.golang.org/p/_osjMqL6Nj
package main import ( "fmt" "strconv" ) func main() { i, err := strconv.ParseInt("123456", 10, 8) fmt.Println(i, err) }
źródło
int64
doint
na GOARCH amd64 iint32
dlaint
32-bitowych GOARCHes. Przynajmniej w przypadku domyślnego kompilatora nie jestem pewien co do gccgo. Zatem „int
może być większe niż 32-bitowe…” to nie tylko spekulacje, jest raczej prawdopodobne, ponieważ 64-bitowe cele kompilacji są ogólnie uważane za główną gałąź w Go.ParseInt
zawsze zwracaint64
wartość. W zależności odbitSize
tej wartości będzie pasować doint
,int8
,int16
,int32
, lubint64
. Jeśli wartość nie może być reprezentowana przez liczbę całkowitą ze znakiem o rozmiarze podanym przezbitSize
, toerr.Err = ErrRange
.int
jest 32- lub 64-bitowy, w zależności od implementacji. Zwykle jest to 32 bity dla kompilatorów 32-bitowych i 64 bity dla kompilatorów 64-bitowych.Aby sprawdzić rozmiar
int
lubuint
, użyjstrconv.IntSize
.Na przykład,
package main import ( "fmt" "runtime" "strconv" ) func main() { fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS) fmt.Println(strconv.IntSize) }
Wynik:
gc amd64 linux 64
źródło
strconv.ParseInt
i przyjaciele zwracają wersje 64-bitowe, aby interfejs API był czysty i prosty. W przeciwnym razie należałoby utworzyć oddzielne wersje dla każdego możliwego typu zwracanego. Lub powrótinterface{}
, który następnie musiałby przejść przez potwierdzenie typu. Żadne z nich nie jest idealne.int64
jest wybrany, ponieważ może pomieścić dowolną liczbę całkowitą do obsługiwanych 64-bitów włącznie. Rozmiar bitu, który przekazujesz do funkcji, zapewnia, że wartość jest prawidłowo zamocowana w odpowiednim zakresie. Możesz więc po prostu wykonać konwersję typu na zwróconej wartości, aby przekształcić ją w dowolny typ liczby całkowitej, którego potrzebujesz.Jeśli chodzi o różnicę między
int
iint64
, jest to zależne od architektury.int
jest po prostu aliasem dla 32-bitowej lub 64-bitowej liczby całkowitej, w zależności od architektury, dla której kompilujesz.Dla wnikliwego oka: zwracana wartość jest liczbą całkowitą ze znakiem. Istnieje oddzielna
strconv.ParseUint
funkcja dla liczb całkowitych bez znaku, która zwracauint64
i stosuje to samo rozumowanie, jak wyjaśniono powyżej.źródło
int
jest to po prostu alias - w rzeczywistości jest to odrębny typ. golang.org/pkg/builtin/#inttype int int32
należy traktować jako jedyny i odrębny typ. Przede wszystkim dlatego, że umożliwia zdefiniowanie nowej funkcjonalności dlaint
typu poprzez zastosowanie nowych metod.strconv.Atoi()
Myślę, że dla twoich celów byłoby wygodniej.Inne odpowiedzi były dość wyczerpujące, jeśli chodzi o wyjaśnienie
int
typu, ale myślę, że link do specyfikacji języka Go jest zasługujący na to: http://golang.org/ref/spec#Numeric_typesźródło
W języku Go lang każdy typ jest traktowany jako oddzielny typ danych, którego nie można używać zamiennie z typem podstawowym. Na przykład,
type CustomInt64 int64
W powyższej deklaracji CustomInt64 i wbudowany int64 są dwoma oddzielnymi typami danych i nie mogą być używane zamiennie.
To samo dotyczy int, int32 i int64, wszystkie są oddzielnymi typami danych, których nie można używać zamiennie. Gdzie int32 to 32, jego typ całkowity, int64 to 64 bity, a rozmiar ogólnego typu int zależy od platformy. Ma 32 bity szerokości w systemie 32-bitowym i 64 bity w systemie 64-bitowym. Dlatego musimy być ostrożni i konkretni podczas określania ogólnych typów danych, takich jak int, uint i float. Może to spowodować problem w kodzie i spowoduje awarię aplikacji na innej platformie.
źródło