Вступление
В Go типы данных используются для классификации одного конкретного типа данных, определения значений, которые вы можете назначить типу, и операций, которые вы можете выполнять над ним. При программировании бывают случаи, когда вам нужно преобразовывать значения между типами, чтобы манипулировать значениями по-другому. Например, вам может потребоваться объединить числовые значения со строками или представить десятичные разряды в числах, которые были инициализированы как целочисленные значения. Сгенерированным пользователем данным часто автоматически присваивается строковый тип данных, даже если он состоит из чисел; для выполнения математических операций с этим вводом вам необходимо преобразовать строку в числовой тип данных.
Так как Go - язык со статической типизацией,data types are bound to variables, а не значения. Это означает, что если вы определяете переменную какint
, она может быть толькоint
; вы не можете присвоить емуstring
без преобразования типа данных переменной. Статическая природа типов данных в Go придает еще большее значение изучению способов их преобразования.
Этот учебник проведет вас через преобразование чисел и строк, а также предоставит примеры, которые помогут познакомиться с различными вариантами использования.
Преобразование типов чисел
Go имеет несколько числовых типов на выбор. В первую очередь они делятся на два основных типа:integers иfloating-point numbers.
Есть много ситуаций, в которых вы можете захотеть конвертировать между числовыми типами. Преобразование междуdifferent sizes of numeric types может помочь оптимизировать производительность для определенных типов системной архитектуры. Если у вас есть целое число из другой части вашего кода и вы хотите разделить его, вы можете преобразовать целое число в число с плавающей точкой, чтобы сохранить точность операции. Кроме того, работа с длительностями времени обычно включает в себя целочисленное преобразование. Чтобы справиться с этими ситуациями, Go имеет встроенныйtype conversions для большинства числовых типов.
Преобразование между целочисленными типами
Go имеет много целочисленных типов данных для выбора. Когда использовать одно вместо другого, обычно больше примерноperformance; однако будут случаи, когда вам нужно будет преобразовать один целочисленный тип в другой. Например, Go иногда автоматически генерирует числовые значения какint
, которые могут не соответствовать вашему входному значению. Если бы ваше входное значение былоint64
, вы не смогли бы использовать числаint
иint64
в одном и том же математическом выражении, пока вы не преобразовали их типы данных в соответствие.
Предположим, у вас естьint8
, и вам нужно преобразовать его вint32
. Вы можете сделать это, обернув его в преобразование типаint32()
:
var index int8 = 15
var bigIndex int32
bigIndex = int32(index)
fmt.Println(bigIndex)
Output15
Этот блок кода определяетindex
как тип данныхint8
иbigIndex
как тип данныхint32
. Чтобы сохранить значениеindex
вbigIndex
, он преобразует тип данных вint32
. Это делается путем обертывания преобразованияint32()
вокруг переменнойindex
.
Чтобы проверить свои типы данных, вы можете использовать инструкциюfmt.Printf
и команду%T
со следующим синтаксисом:
fmt.Printf("index data type: %T\n", index)
fmt.Printf("bigIndex data type: %T\n", bigIndex)
Outputindex data type: int8
bigIndex data type: int32
Поскольку здесь используется глагол%T
, оператор печати выводит тип переменной, а не фактическое значение переменной. Таким образом, вы можете подтвердить преобразованный тип данных.
Вы также можете преобразовать большее целочисленное значение в меньшее целое число:
var big int64 = 64
var little int8
little = int8(big)
fmt.Println(little)
Output64
Имейте в виду, что при преобразовании целых чисел вы потенциально можете превысить максимальное значение типа данных иwraparound:
var big int64 = 129
var little = int8(big)
fmt.Println(little)
Output-127
Обтекание происходит, когда значение преобразуется в тип данных, который слишком мал для его хранения. В предыдущем примере 8-битный тип данныхint8
не имел достаточно места для хранения 64-битной переменнойbig
. Следует всегда соблюдать осторожность при преобразовании типа данных с большим числом в тип данных с меньшим числом, чтобы избежать случайного усечения данных.
Преобразование целых чисел в числа с плавающей точкой
Преобразование целых чисел в числа с плавающей точкой в Go похоже на преобразование одного целочисленного типа в другой. Вы можете использовать встроенные преобразования типов, обернувfloat64()
илиfloat32()
вокруг целого числа, которое вы конвертируете:
var x int64 = 57
var y float64 = float64(x)
fmt.Printf("%.2f\n", y)
Output57.00
Этот код объявляет переменнуюx
типаint64
и инициализирует ее значение57
.
var x int64 = 57
Обертывание преобразованияfloat64()
вокругx
преобразует значение57
в значение с плавающей запятой57.00
.
var y float64 = float64(x)
Команда печати%.2f
указываетfmt.Printf
форматировать число с плавающей запятой с двумя десятичными знаками.
Вы также можете использовать этот процесс для переменной. Следующий код объявляетf
равным57
, а затем распечатывает новое значение с плавающей запятой:
var f float64 = 57
fmt.Printf("%.2f\n", f)
Output57.00
Используяfloat32()
илиfloat64()
, вы можете преобразовать целые числа в числа с плавающей запятой. Далее вы узнаете, как преобразовать числа с плавающей точкой в целые числа.
Преобразование числа с плавающей точкой в целые числа
Go может преобразовывать числа с плавающей точкой в целые числа, но программа теряет точность числа с плавающей точкой.
Обертывание чисел с плавающей запятой вint()
или в один из его архитектурно-независимых типов данных работает аналогично тому, как вы использовали его для преобразования из одного целочисленного типа в другой. Вы можете добавить число с плавающей точкой в скобках, чтобы преобразовать его в целое число:
var f float64 = 390.8
var i int = int(f)
fmt.Printf("f = %.2f\n", f)
fmt.Printf("i = %d\n", i)
Outputf = 390.80
i = 390
Этот синтаксис преобразует число с плавающей запятой390.8
в целое число390
, отбрасывая десятичный разряд.
Вы также можете использовать это с переменными. Следующий код объявляетb
равным125.0
иc
как равным390.8
, а затем выводит их как целые числа. Краткое объявление переменной (:=
) сокращает синтаксис:
b := 125.0
c := 390.8
fmt.Println(int(b))
fmt.Println(int(c))
Output125
390
При преобразовании чисел с плавающей запятой в целые числа с типомint()
Go обрезает десятичное и оставшееся числа числа с плавающей запятой для создания целого числа. Обратите внимание: даже если вы захотите округлить 390,8 до 391, Go не будет делать этого через типint()
. Вместо этого он опустит десятичную дробь.
Числа, преобразованные через деление
При делении целочисленных типов в Go результатом также будет целочисленный тип, с отброшеннымmodulus или остатком:
a := 5 / 2
fmt.Println(a)
Output2
Если при делении любой из числовых типов является плавающим, то все типы будут автоматически объявлены как плавающие:
a := 5.0 / 2
fmt.Println(a)
Output2.5
Это делит число с плавающей запятой5.0
на целое число2
, а ответ2.5
представляет собой число с плавающей запятой, которое сохраняет десятичную точность.
В этом разделе вы конвертировали данные разных типов, в том числе целые и числа с плавающей точкой. Далее вы узнаете, как конвертировать числа и строки.
Преобразование со строками
string - это последовательность из одного или нескольких символов (букв, цифр или символов). Строки являются распространенной формой данных в компьютерных программах, и вам может понадобиться преобразовывать строки в числа или числа в строки довольно часто, особенно когда вы принимаете пользовательские данные.
Преобразование чисел в строки
Вы можете преобразовывать числа в строки, используя методstrconv.Itoa
из пакетаstrconv
в стандартной библиотеке Go. Если вы передадите число или переменную в скобки метода, это числовое значение будет преобразовано в строковое значение.
Во-первых, давайте посмотрим на преобразование целых чисел. Чтобы преобразовать целое число12
в строковое значение, вы можете передать12
в методstrconv.Itoa
:
package main
import (
"fmt"
"strconv"
)
func main() {
a := strconv.Itoa(12)
fmt.Printf("%q\n", a)
}
При запуске этой программы вы получите следующий вывод:
Output"12"
Кавычки вокруг числа 12 означают, что число больше не является целым числом, а теперь является строковым значением.
Вы использовали оператор присваивания:=
как для объявления новой переменной с именемa
, так и для присвоения значения, возвращаемого функциейstrconv.Itoa()
. В этом случае вы присвоили переменной значение12
. Вы также использовали глагол%q
в функцииfmt.Printf
, который предписывает функции заключать указанную строку в кавычки.
С помощью переменных вы можете начать понимать, насколько практичным может быть преобразование целых чисел в строки. Допустим, вы хотите отслеживать ежедневный прогресс пользователя в программировании и вводите, сколько строк кода они пишут за раз. Вы хотели бы показать этот отзыв пользователю и одновременно распечатывать строковые и целочисленные значения:
package main
import (
"fmt"
)
func main() {
user := "Sammy"
lines := 50
fmt.Println("Congratulations, " + user + "! You just wrote " + lines + " lines of code.")
}
Когда вы запустите этот код, вы получите следующую ошибку:
Outputinvalid operation: ("Congratulations, " + user + "! You just wrote ") + lines (mismatched types string and int)
Вы не можете объединять строки и целые числа в Go, поэтому вам придется преобразовать переменнуюlines
в строковое значение:
package main
import (
"fmt"
"strconv"
)
func main() {
user := "Sammy"
lines := 50
fmt.Println("Congratulations, " + user + "! You just wrote " + strconv.Itoa(lines) + " lines of code.")
}
Теперь, когда вы запустите код, вы получите следующий вывод, который поздравляет вашего пользователя с его прогрессом:
OutputCongratulations, Sammy! You just wrote 50 lines of code.
Если вы хотите преобразовать число с плавающей точкой в строку, а не в целое число в строку, выполните аналогичные шаги и формат. Когда вы передаете float методуfmt.Sprint
из пакетаfmt
в стандартной библиотеке Go, будет возвращено строковое значение float. Вы можете использовать либо само значение с плавающей точкой, либо переменную:
package main
import (
"fmt"
)
func main() {
fmt.Println(fmt.Sprint(421.034))
f := 5524.53
fmt.Println(fmt.Sprint(f))
}
Output421.034
5524.53
Вы можете проверить, чтобы убедиться, что это правильно, связав строку:
package main
import (
"fmt"
)
func main() {
f := 5524.53
fmt.Println("Sammy has " + fmt.Sprint(f) + " points.")
}
OutputSammy has 5524.53 points.
Вы можете быть уверены, что ваш float был правильно преобразован в строку, потому что конкатенация была выполнена без ошибок.
Преобразование строк в числа
Строки можно преобразовать в числа с помощью пакетаstrconv
в стандартной библиотеке Go. В пакетеstrconv
есть функции для преобразования целочисленных и числовых типов. Это очень распространенная операция при приеме ввода от пользователя. Например, если у вас есть программа, которая запрашивает возраст человека, когда они вводят ответ, он фиксируется какstring
. Затем вам нужно будет преобразовать его вint
, чтобы делать с ним какие-либо математические вычисления.
Если в вашей строке нет десятичных знаков, вы, скорее всего, захотите преобразовать ее в целое число с помощью функцииstrconv.Atoi
. Если вы знаете, что будете использовать число как число с плавающей запятой, вы должны использоватьstrconv.ParseFloat
.
Давайте используем пример того, как пользователь Sammy отслеживает строки кода, написанные каждый день. Возможно, вы захотите манипулировать этими значениями с помощью математики, чтобы обеспечить более интересную обратную связь для пользователя, но эти значения в настоящее время хранятся в строках:
package main
import (
"fmt"
)
func main() {
lines_yesterday := "50"
lines_today := "108"
lines_more := lines_today - lines_yesterday
fmt.Println(lines_more)
}
Outputinvalid operation: lines_today - lines_yesterday (operator - not defined on string)
Поскольку два числовых значения были сохранены в строках, вы получили ошибку. Операнд-
для вычитания не является допустимым операндом для двух строковых значений.
Измените код, включив методstrconv.Atoi()
, который преобразует строки в целые числа, что позволит вам выполнять математические вычисления со значениями, которые изначально были строками. Поскольку существует вероятность сбоя при преобразовании строки в целое число, вы должны проверить наличие ошибок. Вы можете использовать операторif
, чтобы проверить, было ли преобразование успешным.
package main
import (
"fmt"
"log"
"strconv"
)
func main() {
lines_yesterday := "50"
lines_today := "108"
yesterday, err := strconv.Atoi(lines_yesterday)
if err != nil {
log.Fatal(err)
}
today, err := strconv.Atoi(lines_today)
if err != nil {
log.Fatal(err)
}
lines_more := today - yesterday
fmt.Println(lines_more)
}
Поскольку строка может не быть числом, методstrconv.Atoi()
вернет как преобразованный тип, так и потенциальную ошибку. При преобразовании изlines_yesterday
с помощью функцииstrconv.Atoi
вы должны проверить возвращаемое значениеerr
, чтобы убедиться, что значение было преобразовано. Еслиerr
неnil
, это означает, чтоstrconv.Atoi
не удалось успешно преобразовать строковое значение в целое число. В этом примере вы использовали операторif
для проверки наличия ошибки, а если ошибка была возвращена, вы использовалиlog.Fatal
для регистрации ошибки и выхода из программы.
Когда вы запустите предыдущий код, вы получите:
Output58
Теперь попробуйте преобразовать строку, которая не является числом:
package main
import (
"fmt"
"strconv"
)
func main() {
a := "not a number"
b, err := strconv.Atoi(a)
fmt.Println(b)
fmt.Println(err)
}
Вы получите следующую ошибку:
Output0
strconv.Atoi: parsing "not a number": invalid syntax
Посколькуb
был объявлен, ноstrconv.Atoi
не удалось выполнить преобразование, значение никогда не было присвоеноb
. Обратите внимание, чтоb
имеет значение0
. Это потому, что Go имеет значения по умолчанию, называемые нулевыми значениями в Go. strconv.Atoi
выдает ошибку, описывающую, почему не удалось преобразовать строку.
Преобразование строк и байтов
Строки в Go хранятся в виде фрагмента байтов. В Go вы можете преобразовать фрагмент байтов в строку, заключив его в соответствующие преобразования[]byte()
иstring()
:
package main
import (
"fmt"
)
func main() {
a := "my string"
b := []byte(a)
c := string(b)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
Здесь вы сохранили строковое значение вa
, затем преобразовали его в фрагмент байтовb
, а затем преобразовали этот фрагмент байтов обратно в строку какc
. Затем вы выводите на экранa
,b
иc
:
Outputmy string
[109 121 32 115 116 114 105 110 103]
my string
Первая строка вывода - это исходная строкаmy string
. Вторая распечатанная строка - это фрагмент байта, который составляет исходную строку. Третья строка показывает, что фрагмент байта можно безопасно преобразовать обратно в строку и распечатать обратно.
Заключение
В этом руководстве показано, как преобразовать несколько важных собственных типов данных в другие типы данных, в основном с помощью встроенных методов. Возможность конвертировать типы данных в Go позволит вам делать такие вещи, как принимать пользовательский ввод и выполнять математические операции для разных типов чисел. Позже, когда вы будете использовать Go для написания программ, которые принимают данные из множества различных источников, таких как базы данных и API, вы будете использовать эти методы преобразования, чтобы убедиться, что вы можете действовать в отношении ваших данных. Вы также сможете оптимизировать хранение путем преобразования данных в меньшие типы данных.
Если вам нужен более глубокий анализ типов данных в Go, ознакомьтесь с нашей статьейUnderstanding Data Types in Go.