Подтвердить что ты не робот

В чем разница между int и int64 в Go?

У меня есть строка, содержащая целое число (которое было прочитано из файла).

Я пытаюсь преобразовать string в int с помощью 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.

4b9b3361

Ответ 1

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 равно 8

http://play.golang.org/p/_osjMqL6Nj

package main

import (
    "fmt"
    "strconv"
)

func main() {
    i, err := strconv.ParseInt("123456", 10, 8)
    fmt.Println(i, err)
}

Ответ 2

Пакет strconv

func ParseInt

func ParseInt(s string, base int, bitSize int) (i int64, err error)

ParseInt интерпретирует строку s в данной базе (от 2 до 36) и возвращает соответствующее значение i. Если base == 0, база подразумевается префикс строки: база 16 для "0x", база 8 для "0" и база 10 в противном случае.

Аргумент bitSize указывает целочисленный тип, который должен вписываться в. Размер бит 0, 8, 16, 32 и 64 соответствует int, int8, int16, int32 и int64.

Ошибки, возвращаемые ParseInt, имеют конкретный тип * NumError и include err.Num = s. Если s пусто или содержит недопустимые цифры, err.Err = ErrSyntax; если значение, соответствующее s, не может быть представлено целым знаком со знаком данного размера, err.Err = ErrRange.

ParseInt всегда возвращает значение int64. В зависимости от bitSize это значение будет соответствовать int, int8, int16, int32 или int64. Если значение не может быть представлено целым числом со знаком размера, заданным bitSize, то err.Err = ErrRange.

Спецификация языка программирования Go

Числовые типы

Значение n-разрядного целого числа равно n бит и представлено с использованием две арифметики.

int8        the set of all signed  8-bit integers (-128 to 127)
int16       the set of all signed 16-bit integers (-32768 to 32767)
int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

Существует также набор предопределенных числовых типов с конкретные размеры реализации:

uint     either 32 or 64 bits
int      same size as uint

int - 32 или 64 бита, в зависимости от реализации. Обычно это 32 бита для 32-битных компиляторов и 64 бит для 64-битных компиляторов.

Чтобы узнать размер int или uint, используйте strconv.IntSize.

Пакет strconv

Constants

const IntSize = intSize

IntSize - это размер в битах значения int или uint.

Например,

package main

import (
    "fmt"
    "runtime"
    "strconv"
)

func main() {
    fmt.Println(runtime.Compiler, runtime.GOARCH, runtime.GOOS)
    fmt.Println(strconv.IntSize)
}

Вывод:

gc amd64 linux
64

Ответ 3

strconv.ParseInt и друзья возвращают 64-битные версии, чтобы поддерживать API в чистоте и простоте. Другим нужно было бы создать отдельные версии для каждого возможного типа возврата. Или верните interface{}, который затем должен будет пройти через утверждение типа. Ни один из них не идеален.

int64 выбирается, поскольку он может содержать любой целочисленный размер вплоть до 64-битных поддерживаемых 64-битных включений. Размер бит, который вы передаете в функцию, обеспечивает правильное зажатие значения в правильном диапазоне. Таким образом, вы можете просто преобразовать тип в возвращаемое значение, чтобы превратить его в любой тип целого типа, который вам нужен.

Что касается разницы между int и int64, это зависит от архитектуры. int является просто псевдонимом для 32-разрядного или 64-разрядного целого числа, в зависимости от архитектуры, которую вы компилируете.

Для проницательного глаза: возвращаемое значение представляет собой целое число со знаком. Существует отдельная функция strconv.ParseUint для целых чисел без знака, которая возвращает uint64 и следует тем же рассуждениям, что объяснялось выше.

Ответ 4

Для ваших целей strconv.Atoi() было бы более удобно, я думаю.

Другие ответы были довольно исчерпывающими в объяснении типа int, но я думаю, что здесь есть ссылка на спецификацию языка Go: http://golang.org/ref/spec#Numeric_types