What is the difference between a defined type (type A B) and an alias (type A = B)?
Question 32MediumGo 1.22 to 1.25
type Celsius float64 creates a new, distinct type. It has the same underlying type, but it doesn't inherit the methods of the original named type, and you need explicit conversions to mix it with the original. type A = B is an alias: another name for exactly the same type, with the same methods and full interchangeability. Aliases were added to support gradual refactoring across packages. Since Go 1.24, aliases can have type parameters.
type MyMutex sync.Mutex
var m MyMutex
// m.Lock() // compile error: MyMutex has no method Lock
type Locker = sync.Mutex
var l Locker
l.Lock() // OK: same type as sync.Mutex
type Celsius float64
type Fahrenheit float64
c := Celsius(100)
// f := Fahrenheit(0) + c // compile error: mismatched types
f := Fahrenheit(c*9/5 + 32) // explicit conversion
// Methods of an EMBEDDED field survive in a defined struct type:
type SafeMap struct {
sync.Mutex
m map[string]int
}
type Other SafeMap // Other still has Lock/Unlock (promoted from the embedded field),
// but no methods declared directly on SafeMap
Why use defined types: type safety for units and IDs, attaching methods (for example type Handler func(...) with a ServeHTTP method), and building enums. byte and rune are built-in aliases for uint8 and int32, and any is an alias for interface{}.
More on Language Fundamentals & Types
- Q30How does struct embedding affect method sets and name resolution?
- Q31Why is an interface holding a nil pointer not equal to nil? What does this print?
- Q33Arrays vs slices as values: what does this print?
- Q34How does Go handle integer overflow, division, and conversions between numeric types?
- Q35How did loop variable semantics change in Go 1.22, and what does this print?
- Q36How do range-over-func iterators (Go 1.23) work? What does this print?