Преобразование типов – это, казалось бы, простая концепция в Golang, но если вы новичок в программировании или новичок в языке, то все может показаться сложным для полного понимания вначале, независимо от того, насколько простым оно кажется экспертам. Цель этой статьи – дать второе объяснение преобразования типов в Golang с примерами.
Необходимые условия: Основная аудитория этой статьи – те, кто уже узнал о преобразовании типов в Golang, но нуждается в еще одном объяснении, чтобы лучше усвоить концепцию. Однако, имея представление об основах Golang, таких как объявление переменных и функции, вы все равно сможете понять смысл статьи.
Что такое преобразование типов в Golang
Преобразование типов – это способ преобразования значения одного типа данных в другой тип данных. Приведение типов здесь похоже на то, что известно как Type casting в некоторых других языках, например, в C. Однако в Go термина typecasting не существует, вместо него есть просто приведение типов. Скорее всего, это связано с тем, что в Golang преобразование типов работает немного по-другому. Вам всегда нужно явно указать, что вы преобразовываете данные одного типа в другой тип, чтобы преобразование типов состоялось. В некоторых других языках, таких как C, неявное преобразование типов возможно, если просто использовать значение там, где это необходимо, и компилятор автоматически преобразует значение в соответствующий тип данных, подходящий для выполняемой операции. Пример, показывающий синтаксис преобразования типов в Go:
package main
import "fmt"
func main() {
var price float64 = 2.5
var amount int = 5
total := price * float64(amount) // convert amount to float64
fmt.Println("Total price is this:", total)
}
// Output: Total price is this: 12.5
Мы видим, что в приведенном выше коде, чтобы выполнить арифметическую операцию с обеими переменными и получить итоговую сумму, нам нужно сначала преобразовать цену, которая изначально была целым числом, в float64 с помощью float(amount)
. Если этого не сделать, возникнет ошибка компиляции.
Когда вы создаете псевдоним типа и вам нужно преобразовать одно значение в псевдоним типа, вы используете тот же синтаксис:
type userId int // Create type alias
newUser := userId(9) // Convert 9 from int to userId
Зачем нужно преобразование типов
Обычная причина для выполнения преобразования типов в Go – это использование определенных характеристик типа данных при использовании значения из переменной другого типа данных. Так как значение, которое вы собираетесь использовать, не обладает свойствами, необходимыми для выполнения действия, вы преобразуете его к типу, обладающему этими свойствами. Обратите внимание, что когда вы преобразуете значение из переменной в другой тип данных, исходное объявление переменной сохраняет свой назначенный или утвержденный тип данных, оно не меняет тип. Пример с использованием кода, который мы написали ранее, на этот раз мы также выводим тип amount
после преобразования значения из нее:
package main
import "fmt"
func main() {
var price float64 = 2.5
var amount int = 5
total := price * float64(amount) // convert amount to float64
fmt.Println("Total price is this:", total)
fmt.Printf("type of amount is still %T", amount) // print out the data type of `amount`
}
// Output:
// Total price is this: 12.5
// type of amount is still int
Мы использовали глагол %T
внутри Printf
, чтобы вывести тип данных переменной amount
, и видим, что она по-прежнему остается целым числом.
Некоторые другие способы выполнения преобразования типов в Go
В предыдущих примерах мы преобразовывали только типы чисел и использовали синтаксис T()
. Мы преобразовывали целые числа в плавающие, которые являются обоими типами чисел. Обратите внимание, что при преобразовании числа с плавающей запятой в целое число, новое число потеряет все десятичные знаки, которые были у него, когда оно еще было числом с плавающей запятой. Например, при преобразовании 15.6
из float в int, вы получите 15
, а не 15.6
. Помните об этом при преобразовании из float в int.
Помимо преобразования между числами, мы также можем преобразовывать между строками и числами. Для этого вам нужно импортировать и использовать пакет strconv
из стандартной библиотеки Go. Рассмотрим несколько примеров использования этого пакета:
Преобразование из строки в целое число: Для преобразования строки в целое число мы используем функцию strconv.Atoi()
. Рассмотрим, как это сделать на примере программы для отслеживания количества оставшихся мест в автобусе после покупки пользователем проездного билета:
package main
import (
"fmt"
"log"
"strconv"
)
func main() {
var seatsRemaining int = 9
var howManyTickets string = "3"
// Convert howManyTickets to integer and assign it to numOfTickets
numOfTickets, err := strconv.Atoi(howManyTickets)
// Check if an error occurred during the conversion
if err != nil {
log.Fatal(err)
}
seatsRemaining -= numOfTickets
fmt.Println(seatsRemaining)
}
// Output: 6
Всегда существует вероятность того, что преобразование строки в целое число может завершиться неудачно, поэтому обычно проверяется, произошла ли ошибка, если да, то нужно ее устранить, в противном случае продолжить работу с программой. После выполнения приведенного выше кода без ошибок мы должны получить 6
.
Преобразование из числа в строку: В данном случае используется функция strconv.Itoa()
. В этом примере мы просто выводим сообщение о том, сколько мест в автобусе осталось, но поскольку количество оставшихся мест хранится в виде числа, нам нужно преобразовать число в строку, чтобы включить его в наше сообщение:
package main
import (
"fmt"
"strconv"
)
func main() {
// Number of bus seats remaining
seatsRemaining := 6
fmt.Println("there are", strconv.Itoa(seatsRemaining), " seats remaining in this bus.")
}
Заключение
До сих пор мы объясняли, как работает преобразование типов в Go, а также его синтаксис и какой пакет использовать при преобразовании между строками и числами. Главное, что нужно усвоить: в Go необходимо явно преобразовывать типы, поскольку неявное преобразование не поддерживается, а когда вы преобразуете значение между типами, начальное объявление переменной, в которой хранилось значение, остается исходного типа, оно не изменяется.