Последнее обновление: 20.12.2017
Все данные, которые хранятся в памяти, по сути представляют просто набор битов. И именно тип данных определяет, как будут интерпретироваться эти данные и какие операции с ними можно произодить. Язык Go является статически типизированным языком, то есть все используемые в программе данные имеют определенный тип.
Go имеет ряд встроенных типов данных, а также позволяет определять свои типы. Рассмотрим базовые встроенные типы данных, которые мы можем использовать.
Ряд типов представляют целые числа:
int8: представляет целое число от -128 до 127 и занимает в памяти 1 байт (8 бит)
int16: представляет целое число от -32768 до 32767 и занимает в памяти 2 байта (16 бит)
int32: представляет целое число от -2147483648 до 2147483647 и занимает 4 байта (32 бита)
int64: представляет целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт (64 бита)
uint8: представляет целое число от 0 до 255 и занимает 1 байт
uint16: представляет целое число от 0 до 65535 и занимает 2 байта
uint32: представляет целое число от 0 до 4294967295 и занимает 4 байта
uint64: представляет целое число от 0 до 18 446 744 073 709 551 615 и занимает 8 байт
byte: синоним типа uint8
, представляет целое число от 0 до 255 и занимает 1 байт
rune: синоним типа int32
, представляет целое число от -2147483648 до 2147483647 и занимает 4 байта
int: представляет целое число со знаком, которое в зависимости о платформы может занимать либо 4 байта, либо 8 байт. То есть соответствовать либо int32, либо int64.
uint: представляет целое беззнаковое число только без знака, которое, аналогично типу int, в зависимости о платформы может занимать либо 4 байта, либо 8 байт. То есть соответствовать либо uint32, либо uint64.
Здесь несложно запомнить, что есть типы со знаком (то есть которые могут быть отрицательными) и есть безнаковые положительные типы, которые начинаются на префикс u (uint32). Ну и также есть byte — синоним для uint8 и rune — синоним для int32.
Стоит отметить типы int и uint. Они имеют наиболее эффективный размер для определенной платформы (32 или 64 бита). Это наиболее используемый тип для представления целых чисел в программе. Причем различные компиляторы могут предоставлять различный размер для этих типов даже для одной и той же платформы.
Примеры определения переменных, которые представляют целочисленные типы:
var a int8 = -1 var b uint8 = 2 var c byte = 3 // byte - синоним типа uint8 var d int16 = -4 var f uint16 = 5 var g int32 = -6 var h rune = -7 // rune - синоним типа int32 var j uint32 = 8 var k int64 = -9 var l uint64 = 10 var m int = 102 var n uint = 105
Для представления дробных чисел есть два типа:
float32: представляет число с плавающей точкой от 1. 4*10-45 до 3.4*1038(для положительных). Занимает в памяти 4 байта (32 бита)
float64: представляет число с плавающей точкой от 4.9*10-324 до 1.8*10308 (для положительных) и занимает 8 байт.
Тип float32 обеспечивает шесть десятичных цифр точности, в то время как точность, обеспечиваемая типом float64, составляет около 15 цифр
Примеры использования типов float32 и float64:
var f float32 = 18 var g float32 = 4.5 var d float64 = 0.23 var pi float64 = 3.14 var e float64 = 2.7
В качестве разделителя между целой и дробной частью применяется точка.
Существуют отдельные типы для представления комплексных чисел:
complex64: комплексное число, где вещественная и мнимая части представляют числа float32
complex128: комплексное число, где вещественная и мнимая части представляют числа float64
Пример использования:
var f complex64 = 1+2i var g complex128 = 4+3i
Логический тип или тип bool может иметь одно из двух значений: true (истина) или false (ложь).
var isAlive bool = true var isEnabled bool = false
Строки представлены типом string. В Go строке соответствует строковый литерал — последовательность символов, заключенная в двойные кавычки:
var name string = "Том Сойер"
Если переменной не присвоено значение, то она имеет значение по умолчанию, которое определено для ее типа. Для числовых типов это число 0, для логического типа — false, для строк — «»(пустая строка).
При определении переменной мы можем опускать тип в том случае, если мы явно инициализируем переменную каким-нибудь значением:
var name = "Tom"
В этом случае компилятор на основании значения неявно выводит тип переменной. Если присваивается строка, то то соответственно переменная будет представлять тип string, если присваивается целое число, то переменная представляет тип int и т.д.
То же самое по сути происходит при кратком определении переменной, когда также явным образом не указывается тип данных:
name := "Tom"
При этом стоит учитывать, что если мы не указываем у переменной тип, то ей обязательно надо присвоить некоторое начальное значение. Объявление переменной одновременно без указания типа данных и начального значения будет ошибкой:
var name // ! Ошибка
Надо либо указать тип данных (в этом случае переменная будет иметь значение по умолчанию):
var name string
Либо указать начальное значение, на основании которого выводится тип данных:
var name = "Tom"
Либо и то, и другое одновременно:
var name string = "Tom"
Неявная типизация нескольких переменных:
var ( name = "Tom" age = 27 )
или так:
var name, age = "Tom", 27
НазадСодержаниеВперед
спросил
Изменено 1 год, 3 месяца назад
Просмотрено 7к раз
Если у меня есть срез байтов в Go, примерно так:
numBytes := []byte { 0xFF, 0x10 }
Как мне преобразовать его в uint16
значение (0xFF10, 65296)?
вы можете использовать binary. BigEndian.Uint16(numBytes)
как этот рабочий пример кода (с комментариями):
package main Импортировать ( "кодирование/двоичный" "ФМТ" ) основная функция () { числобайт := []байт{0xFF, 0x10} u:= двоичный.BigEndian.Uint16(numBytes) fmt.Printf("%#X %[1]v\n", u) // 0XFF10 65296 }
и посмотреть внутри binary.BigEndian.Uint16(b []byte)
функция (bigEndian) Uint16(b []byte) uint16 { _ = b[1] // проверка границ подсказка компилятору; см. golang.org/issue/14808 вернуть uint16(b[1]) | uint16(b[0])<<8 }
Надеюсь, это поможет.
1
Чтобы объединить два байта в uint16
x := uint16(numBytes[i])<<8 | uint16 (количество байтов [я + 1])
, где i
— начальная позиция uint16. Итак, если ваш массив всегда состоит только из двух элементов, это будет x := uint16(numBytes[0])<<8 | uint16 (число байтов [1])
1
Во-первых, у вас есть срез, а не массив — массив имеет фиксированный размер и должен быть объявлен следующим образом: [2]byte
.
Если бы у вас был только 2-байтовый фрагмент, я бы не стал делать ничего особенного, я бы просто сделал
numBytes := []byte{0xFF, 0x10} n := int(numBytes[0])<<8 + int(numBytes[1]) fmt.Printf("n = 0x%04X = %d\n", n, n)
Детская площадка
РЕДАКТИРОВАТЬ : Только что заметил, что вы хотели uint16
- замените int
на это выше!
Вы можете использовать следующее небезопасное преобразование:
*(*uint16)(unsafe.Pointer(&numBytes[0])
1
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Электронная почта
Обязательно, но не отображается
Электронная почта
Требуется, но не отображается
основной пакет | |
импорт ( | |
"байт" | |
"кодирование/бинарное" | |
"фмт" | |
"отражать" | |
"стрконв" | |
) | |
основная функция () { | |
переменная целочисленнаяпеременная = 123 | |
fmt. Println("intVar: ", intVar) | |
fmt.Println("тип intVar: ", Reflect.TypeOf(intVar)) | |
// в зависимости от того, чего вы хотите добиться, первый метод | |
// это разбить целое значение на отдельные цифры | |
// т. е. от 123 до [1,2,3] | |
// буквально ... целое число в байтовом массиве отдельных цифр | |
var rightMost, tempIntVar int | |
переменная массива байтов [] байт | |
tempIntVar = intVar | |
для { | |
// если использовать leftMost вместо rightMost, нам нужно знать длину | |
// intVar заранее перед применением по модулю. | |
// вместо %10 используем %1e3, где 3 — позиция | |
// но для простоты и возможности обработки динамической длины intVar, | |
// мы используем rightMost и позже меняем порядок среза. | |
rightMost = tempIntVar % 10 | |
byteArray = append(byteArray, byte(rightMost)) // преобразовать одну цифру в байт | |
// обновить tempIntVar, за вычетом обработанного rightMost | |
tempIntVar /= 10 | |
, если tempIntVar == 0 { | |
перерыв | |
} | |
} | |
// нужно изменить порядок | |
fixByteArray := []байт{} | |
для i := диапазон byteArray { | |
n := массив байтов[len(массив байтов)-1-i] | |
fixByteArray = добавить (fixByteArray, n) | |
} | |
//fmt. Println("массив байтов: ", массив байтов) | |
fmt.Println("Срез байтов для целочисленной переменной.") | |
fmt.Println("Байтовый массив целых чисел: ", fixByteArray) | |
fmt.Printf("Байтовый массив целых чисел: % x\n", fixByteArray) | |
fmt.Println("Байтовый массив целых чисел типа: ", Reflect.TypeOf(fixByteArray)) | |
// второй метод, преобразование int напрямую в []byte | |
// если вы знаете машинный код | |
// например, LittleEndian | |
положительный эффект: = новый (байты. Буфер) | |
ошибка := двоичный файл. Запись (бафф, двоичный файл. LittleEndian, uint16 (intVar)) | |
если ошибка != ноль { | |
fmt.Println(ошибка) | |
} | |
intByteArray := buff.Bytes() | |
fmt.Printf("intByteArray: % x\n", intByteArray) | |
fmt.Println("тип intByteArray: ", Reflect.TypeOf(intByteArray)) | |
// проверить, правильно ли 123 переводится в 7b | |
байтI := байт(intVar) | |
fmt. |