Type Aliases / Custom Types
| Since: | Go 1.9(2017) |
|---|
In Go, the type keyword lets you define a custom type based on an existing type. You can add methods to custom types. A type alias (using =) is treated as exactly the same type as the original.
Syntax
type TypeName ExistingType
// Defines a type alias (treated as exactly the same type as the original).
type TypeName = ExistingType
// Adds a method to a custom type.
func (v TypeName) MethodName() ReturnType {
// body
}
Custom Type vs. Type Alias
| Definition | Description |
|---|---|
| type MyType int | Defines a custom type. It is treated as a distinct type from the original (int), so explicit conversion is required for assignment. |
| type MyAlias = int | Defines a type alias. It is treated as exactly the same type as the original (int), so values can be assigned to each other without conversion. |
| func (v MyType) M() | Adds a method to a custom type. You cannot add methods directly to built-in types (such as int or string), but wrapping them in a custom type makes it possible. |
| type TypeName struct{...} | Defines a custom struct type. You can create composite types that hold multiple fields. |
Sample Code
sample_type_alias.go
package main
import "fmt"
// Defines custom types based on float64.
type Celsius float64
type Fahrenheit float64
// Adds a method to the Celsius type.
func (c Celsius) ToFahrenheit() Fahrenheit {
return Fahrenheit(c*9/5 + 32)
}
func (c Celsius) String() string {
return fmt.Sprintf("%.1f°C", float64(c))
}
// A custom type based on string.
type UserID string
func (id UserID) Prefix() string {
return "user_" + string(id)
}
// Example of a type alias (using =).
type Meter = float64 // Treated as exactly the same type as float64.
func main() {
// Custom types are distinguished from their underlying types.
boiling := Celsius(100)
fmt.Println(boiling) // Prints "100.0°C" (the String method is called).
fmt.Println(boiling.ToFahrenheit()) // Prints "212".
// Explicit conversion is required when assigning between a custom type and its underlying type.
var raw float64 = 37.5
body := Celsius(raw) // Converts from float64 to Celsius.
fmt.Println(body) // Prints "37.5°C".
// Using UserID.
id := UserID("42")
fmt.Println(id.Prefix()) // Prints "user_42".
// A type alias is exactly the same as its original type.
var distance Meter = 100.0
var d float64 = distance // Can be assigned without conversion.
fmt.Println(d) // Prints "100".
// Creating enumerated values (enum equivalent) with a custom type.
type Direction int
const (
North Direction = iota
East
South
West
)
dir := North
fmt.Println(dir) // Prints "0".
}
This produces the following output:
go run type_alias.go 100.0°C 212 37.5°C user_42 100 0
Notes
Using custom types lets you distinguish values that share the same underlying type but have different meanings — for example, Celsius vs. Fahrenheit, or UserID vs. ProductID — at the type level. This allows the compiler to catch incorrect assignments at compile time.
Assigning between a custom type and its underlying type requires an explicit type conversion. A type alias (=) is identical to the original type, so no conversion is needed — but you cannot add methods to a type alias.
Go does not have a built-in enum type, but you can achieve the same effect by combining a custom type with iota. Defining custom types improves type safety within the package.
If you find any errors or copyright issues, please contact us.