У меня есть строка, содержащая целое число (которое было прочитано из файла).
Я пытаюсь преобразовать string
файл int
using strconv.ParseInt()
. ParseInt
требует, чтобы я указал размер в битах (размеры битов 0, 8, 16, 32 и 64 соответствуют int, int8, int16, int32 и int64).
Целое число, прочитанное из файла, невелико (то есть должно соответствовать обычному int). Однако, если я передаю битовый размер 0, я получаю результат типа int64
(предположительно, потому что я работаю в 64-битной ОС).
Почему это происходит? Как мне просто получить нормальный int? (Если у кого-то есть краткое руководство о том, когда и почему мне следует использовать разные типы int, это было бы здорово!)
Изменить: я могу преобразовать int64 в обычный int, используя int([i64_var])
. Но я до сих пор не понимаю, почему ParseInt()
мне предоставляется int64, когда я запрашиваю битовый размер 0.
parseInt(s, 0, 0)
, что должно означать base10 (поскольку строка не имеет префикса base). Однако Atoi - это сокращение для вызоваparseInt
с базой , равной 10. Почему базовый параметр влияет на возвращаемый тип?0
означает, что код пытается выяснить это самостоятельно. Но иногда это невозможно.11
(десятичный) vs11
(двоичный) представляют собой совершенно разные значения.parseInt(s, 10, 0)
. Но почему тогда Atoi возвращается,int
аparseInt
возвращает int64?Atoi
было добавлено просто для удобства людей, более знакомых с C API:int atoi ( const char * str );
Ответы:
func ParseInt(s string, base int, bitSize int) (i int64, err error)
ParseInt всегда возвращает
int64
bitSize
определяет диапазон значений. Если значение, соответствующее s, не может быть представлено целым числом со знаком заданного размера, err.Err = ErrRange.http://golang.org/pkg/strconv/#ParseInt
type int int
int - это целочисленный тип со знаком, который имеет размер не менее 32 бита. Однако это отдельный тип, а не псевдоним, скажем, для int32.
http://golang.org/pkg/builtin/#int
Так
int
что в будущем может быть больше 32 бит или в некоторых системах, таких какint
C.Я предполагаю, что в некоторых системах
int64
может быть быстрее,int32
потому что эта система работает только с 64-битными целыми числами.Вот пример ошибки при
bitSize
8http://play.golang.org/p/_osjMqL6Nj
package main import ( "fmt" "strconv" ) func main() { i, err := strconv.ParseInt("123456", 10, 8) fmt.Println(i, err) }
источник
int64
forint
на amd64 GOARCH иint32
forint
на 32-битных GOARCH. По крайней мере, с компилятором по умолчанию я не уверен насчет gccgo. Так что «int
может быть больше 32 бит ...» - это не просто предположение, это на самом деле весьма вероятно, поскольку 64-битные цели компиляции обычно считаются основной веткой в Go.ParseInt
всегда возвращаетint64
значение. В зависимости от тогоbitSize
, это значение будет вписываться вint
,int8
,int16
,int32
, илиint64
. Если значение не может быть представлено целым числом со знаком размера, заданногоbitSize
, тоerr.Err = ErrRange
.int
составляет 32 или 64 бита, в зависимости от реализации. Обычно это 32 бита для 32-битных компиляторов и 64 бита для 64-битных компиляторов.Чтобы узнать размер
int
илиuint
, используйтеstrconv.IntSize
.Например,
package main import ( "fmt" "runtime" "strconv" ) func main() { fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS) fmt.Println(strconv.IntSize) }
Выход:
gc amd64 linux 64
источник
strconv.ParseInt
и друзья возвращают 64-битные версии, чтобы API был чистым и простым. В противном случае пришлось бы создавать отдельные версии для каждого возможного типа возврата. Или returninterface{}
, который затем должен будет пройти утверждение типа. Ни один из них не идеален.int64
выбран, потому что он может содержать любое целое число до поддерживаемых 64 бит включительно. Размер в битах, который вы передаете в функцию, гарантирует, что значение будет правильно зафиксировано в правильном диапазоне. Таким образом, вы можете просто преобразовать тип возвращаемого значения, чтобы преобразовать его в любой требуемый целочисленный тип.Что касается разницы между
int
иint64
, это зависит от архитектуры.int
- это просто псевдоним для 32-битного или 64-битного целого числа, в зависимости от архитектуры, для которой вы компилируете.Для проницательного взгляда: возвращаемое значение - целое число со знаком. Для
strconv.ParseUint
целых чисел без знака существует отдельная функция, которая возвращаетuint64
и следует тем же рассуждениям, что и объяснено выше.источник
int
это просто псевдоним - это на самом деле отдельный тип. golang.org/pkg/builtin/#inttype int int32
следует рассматривать как уникальный и отдельный тип. В частности, потому, что он позволяет определять новые функции дляint
типа посредством применения новых методов.strconv.Atoi()
Думаю, для ваших целей было бы удобнее.Другие ответы были довольно исчерпывающими по поводу объяснения
int
типа, но я думаю, что ссылка на спецификацию языка Go заслуживает здесь: http://golang.org/ref/spec#Numeric_typesисточник
В языке Go каждый тип рассматривается как отдельный тип данных, который не может использоваться взаимозаменяемо с базовым типом. Например,
type CustomInt64 int64
В приведенном выше объявлении CustomInt64 и встроенный int64 являются двумя отдельными типами данных и не могут использоваться взаимозаменяемо.
То же самое и с int, int32 и int64, все это отдельные типы данных, которые нельзя использовать взаимозаменяемо. Где int32 - это 32 его целочисленный тип, int64 - 64 бита, а размер общего типа int зависит от платформы. Он имеет ширину 32 бита в 32-битной системе и 64 бита в 64-битной системе. Поэтому мы должны быть осторожны и конкретны при указании общих типов данных, таких как int, uint и float. Это может вызвать проблему где-то в коде и привести к сбою приложения на другой платформе.
источник