跳过正文
  1. Teches/
  2. 程序语言/
  3. golang/

类型与interface

·672 字·4 分钟
目录

类型拥有方法,接口声明方法(签名)

interface
#

1. 接口%v格式化输出
#

  1. 非空接口:输出的是动态值的 %v 格式化结果
  2. 空接口:同样输出动态值的 %v 格式化结果
  3. 如果类型实现了 String() 方法:%v 会调用该方法
  4. %#v 输出更详细信息:包括类型信息

2. 组合、嵌套
#

</> go
 1// 基础接口
 2type Reader interface {
 3    Read(p []byte) (n int, err error)
 4}
 5
 6type Writer interface {
 7    Write(p []byte) (n int, err error)
 8}
 9
10type Closer interface {
11    Close() error
12}
13
14// 接口组合
15type ReadWriter interface {
16    Reader
17    Writer
18}
19
20type ReadWriteCloser interface {
21    Reader
22    Writer
23    Closer
24}
25
26// 组合+额外方法
27type BufferedReadWriter interface {
28    Reader
29    Writer
30    Buffered() int
31    Peek(n int) ([]byte, error)
32}
33
34// 实现组合接口
35type BufferedIO struct {
36    buffer bytes.Buffer
37}
38
39func (bio *BufferedIO) Read(p []byte) (int, error) {
40    return bio.buffer.Read(p)
41}
42
43func (bio *BufferedIO) Write(p []byte) (int, error) {
44    return bio.buffer.Write(p)
45}
46
47func (bio *BufferedIO) Buffered() int {
48    return bio.buffer.Len()
49}
50
51func (bio *BufferedIO) Peek(n int) ([]byte, error) {
52    if n > bio.buffer.Len() {
53        return nil, io.EOF
54    }
55    data := bio.buffer.Bytes()
56    return data[:n], nil
57}

类型
#

类型实现接口方法,编译时类型值验证接口定义

1. 结构体类型struct
#

嵌入特性(Embedding)
</> go
 1type Animal struct {
 2    Name string
 3}
 4type Dog struct {
 5    Animal // 嵌入结构体(组合而非继承)
 6}
 7func main() {
 8    // 创建 Dog 实例
 9    dog := Dog{
10        Animal: Animal{Name: "Buddy"},
11    }
12    
13    // 访问方式1:通过嵌入类型访问
14    fmt.Println(dog.Animal.Name)  // "Buddy"
15    
16    // 访问方式2:直接访问(提升字段)
17    fmt.Println(dog.Name)         // "Buddy"
18    
19    // 也可以直接设置
20    dog.Name = "Max"
21    fmt.Println(dog.Name)         // "Max"
22}

2. 函数类型
#

</> go
 1// 函数类型实现接口
 2type Handler func(http.ResponseWriter, *http.Request)
 3
 4func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 5    h(w, r)
 6}
 7
 8// 使用
 9func helloHandler(w http.ResponseWriter, r *http.Request) {
10    fmt.Fprintf(w, "Hello!")
11}
12
13func main() {
14    http.Handle("/hello", Handler(helloHandler))
15}

3. 基本类型(int, string 等)
#

</> go
 1// 为基本类型定义新类型
 2type Celsius float64
 3type Fahrenheit float64
 4
 5// 为 Celsius 定义方法
 6func (c Celsius) String() string {
 7    return fmt.Sprintf("%.1f°C", c)
 8}
 9
10// 为 Fahrenheit 定义方法
11func (f Fahrenheit) ToCelsius() Celsius {
12    return Celsius((f - 32) * 5 / 9)
13}
14
15// 使用
16var temp Celsius = 37.5
17fmt.Println(temp.String())  // 37.5°C

4. 切片类型
#

</> go
 1// 为切片定义类型
 2type IntSlice []int
 3
 4// 为切片类型定义方法
 5func (s IntSlice) Sum() int {
 6    total := 0
 7    for _, v := range s {
 8        total += v
 9    }
10    return total
11}
12
13// 使用
14nums := IntSlice{1, 2, 3, 4}
15fmt.Println(nums.Sum())  // 10

5. 映射类型(map)
#

</> go
 1// 为映射定义类型
 2type StringMap map[string]string
 3
 4// 为映射类型定义方法
 5func (m StringMap) Keys() []string {
 6    keys := make([]string, 0, len(m))
 7    for k := range m {
 8        keys.append(k)
 9    }
10    return keys
11}
12
13// 使用
14m := StringMap{"a": "apple", "b": "banana"}
15fmt.Println(m.Keys())  // [a b]

6. 通道类型
#

</> go
 1// 为通道定义类型
 2type ResultChan chan Result
 3
 4// 为通道类型定义方法
 5func (ch ResultChan) SafeClose() {
 6    defer func() {
 7        if recover() != nil {
 8            fmt.Println("Channel already closed")
 9        }
10    }()
11    close(ch)
12}

7. 数组类型
#

</> go
 1// 为数组定义类型
 2type Matrix3x3 [3][3]float64
 3
 4// 为数组类型定义方法
 5func (m Matrix3x3) Determinant() float64 {
 6    // 计算 3x3 矩阵的行列式
 7    return m[0][0]*(m[1][1]*m[2][2]-m[1][2]*m[2][1]) -
 8           m[0][1]*(m[1][0]*m[2][2]-m[1][2]*m[2][0]) +
 9           m[0][2]*(m[1][0]*m[2][1]-m[1][1]*m[2][0])
10}

8. 接口类型 (不常见,但可以)
#

</> go
 1// 为接口类型本身定义方法(罕见用法)
 2type Shape interface {
 3    Area() float64
 4}
 5
 6// 为 Shape 接口类型定义方法
 7func (s Shape) Describe() string {
 8    return "This is a shape"
 9}
10// 注意:这很少见,因为接口通常是其他类型实现的

9. 指针类型 (特例)
#

</> go
1// 为指针类型本身定义方法(不是常见的指针接收者)
2type IntPointer *int
3
4// 这是允许的,但不常用
5func (ip IntPointer) Address() uintptr {
6    return uintptr(unsafe.Pointer(ip))
7}

10. 自定义类型别名 (任意类型的别名)
#

</> go
 1// 任意类型的别名都可以定义方法
 2type UserID string
 3type Money decimal.Decimal
 4type Timestamp time.Time
 5
 6// 为这些别名定义方法
 7func (uid UserID) IsValid() bool {
 8    return len(uid) > 0 && uid[0] != '#'
 9}
10
11func (m Money) Format() string {
12    return fmt.Sprintf("$%.2f", m)
13}
14
15func (t Timestamp) ISOString() string {
16    return time.Time(t).Format(time.RFC3339)
17}