Ответ
В Go есть два похожих, но принципиально разных механизма работы с типами: определение нового типа и создание псевдонима типа.
1. Определение нового типа (Type Definition)
Это основной способ создания собственных типов. Он использует синтаксис type NewType UnderlyingType
.
- Создается новый, отдельный тип.
- Новый тип не является взаимозаменяемым с его базовым типом без явного преобразования.
- Это позволяет компилятору обеспечивать типобезопасность и улучшает читаемость кода, добавляя семантический смысл.
Пример:
// Определяем два новых типа на основе int
type UserID int
type ProductID int
func GetUser(id UserID) {
fmt.Printf("Получение пользователя с ID: %dn", id)
}
func main() {
var uid UserID = 42
var pid ProductID = 100
GetUser(uid) // OK
// GetUser(pid) // Ошибка компиляции: cannot use pid (type ProductID) as type UserID in argument to GetUser
// GetUser(123) // Ошибка компиляции: cannot use 123 (type int) as type UserID in argument to GetUser
// Необходимо явное преобразование типа
var regularInt int = 123
GetUser(UserID(regularInt)) // OK
}
Здесь UserID
и ProductID
— это два разных типа, хотя оба основаны на int
.
2. Псевдоним типа (Type Alias)
Этот механизм был добавлен в Go 1.9. Он использует синтаксис type Alias = OriginalType
.
- Не создает новый тип, а лишь вводит для него второе имя (псевдоним).
- Псевдоним и оригинальный тип полностью взаимозаменяемы.
- Основное предназначение — постепенный рефакторинг большого объема кода, когда нужно переименовать тип, не ломая совместимость.
Пример:
// Определяем тип
type UserID int
// Создаем псевдоним для UserID. Теперь `LocalUserID` и `UserID` - это одно и то же.
type LocalUserID = UserID
func GetUser(id UserID) {
fmt.Printf("Получение пользователя с ID: %dn", id)
}
func main() {
var localId LocalUserID = 42
// Псевдоним можно использовать напрямую, без преобразования
GetUser(localId) // OK
var uid UserID = localId // OK, типы идентичны
fmt.Println(uid)
}
Итог:
- Определение типа (
type T1 T2
) — для создания семантически разных типов и повышения типобезопасности. - Псевдоним типа (
type T1 = T2
) — для рефакторинга и совместимости, когда нужно, чтобы два имени обозначали один и тот же тип.