类型拥有方法,接口声明方法(签名)
interface#
1. 接口%v格式化输出#
- 非空接口:输出的是动态值的 %v 格式化结果
- 空接口:同样输出动态值的 %v 格式化结果
- 如果类型实现了 String() 方法:%v 会调用该方法
- %#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°C4. 切片类型#
</>
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()) // 105. 映射类型(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}