Go类型和接口技巧

编译时检查类型实现接口/类型断言

在 Go 语言中,这行代码 var _ interfaces.CoreServer = (*serverService)(nil) 是一种常用的编译时类型断言惯用法。这行代码并不会在运行时创建变量,而是起到两个主要作用:

  1. 确保类型实现了接口:它断言 serverService 实现了 interfaces.CoreServer 接口。如果 serverService 没有实现 interfaces.CoreServer 接口的所有方法,程序将无法编译。这是一种在编译阶段而非运行时检查接口实现的方式。

  2. 文档作用:这行代码还作为明确的文档说明。它向阅读代码的开发人员清楚地显示 serverService 旨在实现 interfaces.CoreServer 接口。在大型代码库中,这种表示方法特别有用,因为接口及其实现之间的关系可能不会立即清楚。

本质上,这是一个静态检查,确保 serverService 正确实现了 interfaces.CoreServer 接口。如果实现缺少任何方法,将在编译时而不是运行时发现错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type serverService struct {
corev1.UnimplementedCoreServiceServer
ctx context.Context
options options.SrviceOption
streams map[string]corev1.CoreService_AgentServer
mu sync.RWMutex
}

var _ interfaces.CoreServer = (*serverService)(nil)

func NewServerService(ctx context.Context, options options.SrviceOption) interfaces.CoreServer {
return &serverService{
ctx: ctx,
options: options,
streams: make(map[string]corev1.CoreService_AgentServer),
}
}

接口组合

  1. 接口组合:Go 允许通过组合小的接口来创建更大的接口。这是接口重用和模块化设计的有效方式。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type Reader interface {
    Read(p []byte) (n int, err error)
    }

    type Writer interface {
    Write(p []byte) (n int, err error)
    }

    type ReadWriter interface {
    Reader
    Writer
    }

空接口应用

空接口应用:空接口 interface{} 可以用来处理未知类型的值。这在处理动态内容时非常有用,类似于其他语言中的泛型。

1
2
3
func PrintAnything(v interface{}) {
fmt.Println(v)
}

类型选择

类型选择(Type Switch):可以使用类型选择来查询接口值的类型,这在需要根据类型执行不同操作时非常有用。

1
2
3
4
5
6
7
8
switch v := myVar.(type) {
case int:
fmt.Println("Integer:", v)
case string:
fmt.Println("String:", v)
default:
fmt.Println("Unknown type")
}

Go类型和接口技巧
https://abrance.github.io/2024/01/10/domain/golang/Go类型和接口技巧/
Author
xiaoy
Posted on
January 10, 2024
Licensed under