ZetCode

Golang type 关键字

最后修改于 2025 年 5 月 7 日

本教程将介绍如何在 Go 中使用 `type` 关键字。我们将通过创建自定义类型的实际示例来涵盖类型定义。

`type` 关键字可以基于现有类型创建一个新的命名类型,或定义一个新结构。它是构建类型安全程序的基础。

在 Go 中,`type` 可以创建类型别名、结构体类型、接口类型等等。它通过强类型提高了代码的可读性和可维护性。

基本类型别名

`type` 最简单的用法是为现有类型创建别名。此示例演示了从 `float64` 创建 `Celsius` 类型。

basic_type.go
package main

import "fmt"

type Celsius float64

func main() {
    var temp Celsius = 23.5
    fmt.Printf("Temperature: %v°C\n", temp)
    fmt.Printf("Type: %T\n", temp)
}

`Celsius` 是一个独立于 `float64` 的类型,尽管它们共享相同的底层表示。 `%T` 格式化动词会显示类型名称。

结构体类型定义

`type` 通常用于定义结构体类型。此示例创建了一个带有 `name` 和 `age` 字段的 `Person` 结构体。

struct_type.go
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Printf("%+v\n", p)
    fmt.Printf("Name: %s, Age: %d\n", p.Name, p.Age)
}

`Person` 结构体将相关的数据字段分组。结构体字段通过点表示法访问。 `%+v` 格式化动词会显示字段名称。

接口类型

接口定义了类型可以实现的 메서 집합 (method sets)。此示例显示了一个带有 `Area` 方法的基本 `Shape` 接口。

interface_type.go
package main

import (
    "fmt"
    "math"
)

type Shape interface {
    Area() float64
}

type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func main() {
    var s Shape = Circle{Radius: 5}
    fmt.Printf("Area: %.2f\n", s.Area())
}

`Circle` 通过提供 `Area` 方法来实现 `Shape`。接口变量 `s` 可以持有任何满足该接口的类型。

函数类型

`type` 可以定义函数签名。此示例创建了一个用于字符串操作的 `transformer` 函数类型。

func_type.go
package main

import (
    "fmt"
    "strings"
)

type StringTransformer func(string) string

func transform(s string, fn StringTransformer) string {
    return fn(s)
}

func main() {
    upper := func(s string) string {
        return strings.ToUpper(s)
    }
    
    result := transform("hello", upper)
    fmt.Println(result)
}

`StringTransformer` 定义了一个接受和返回字符串的函数类型。这使得可以将函数作为参数传递,同时保持类型安全。

类型嵌入

Go 支持类型嵌入以进行组合。此示例将 `Person` 类型嵌入到 `Employee` 类型中。

embedded_type.go
package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

type Employee struct {
    Person
    Position string
    Salary   float64
}

func main() {
    emp := Employee{
        Person:   Person{Name: "Bob", Age: 40},
        Position: "Developer",
        Salary:   75000,
    }
    
    fmt.Printf("%+v\n", emp)
    fmt.Printf("Name: %s, Position: %s\n", emp.Name, emp.Position)
}

`Employee` 嵌入了 `Person`,继承了其字段和方法。嵌入的字段可以直接访问,无需限定。

类型开关

类型开关可与自定义类型一起使用。此示例通过 `switch` 语句演示类型检查。

type_switch.go
package main

import "fmt"

type ID string
type Number int

func printType(x interface{}) {
    switch v := x.(type) {
    case ID:
        fmt.Printf("ID: %v\n", v)
    case Number:
        fmt.Printf("Number: %v\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

func main() {
    printType(ID("abc123"))
    printType(Number(42))
    printType("test")
}

类型开关会检查接口值的动态类型。每个 `case` 匹配一个特定的类型,而 `default` 处理未匹配的类型。

方法接收者

自定义类型可以拥有方法。此示例向 `Distance` 类型添加了方法。

method_receiver.go
package main

import "fmt"

type Distance float64

func (d Distance) Meters() float64 {
    return float64(d)
}

func (d Distance) Kilometers() float64 {
    return float64(d) / 1000
}

func main() {
    dist := Distance(1500)
    fmt.Printf("%.2f meters = %.2f kilometers\n",
        dist.Meters(), dist.Kilometers())
}

方法在函数名之前使用接收者参数进行定义。 `Distance` 类型获得了 `Meters` 和 `Kilometers` 方法用于单位转换。

来源

Go 语言规范

本教程通过创建自定义类型、结构体、接口和方法的实际示例,讲解了 Go 中的 `type` 关键字。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出所有 Golang 教程