接口断言
# 接口断言
- 因为空接口
interface{}
没有定义任何函数,因此Go
中所有类型都实现了空接口.当一个函数的形参是interface{}
,那么在函数中需要对形参进行断言,从而得到它的真实类型.
# 语法
# 安全类型断言
<目标类型的值>,<布尔参数> := <表达式>.(目标类型)
# 非安全类型断言
<目标类型的值> := <表达式>.(目标类型)
1
2
3
4
5
2
3
4
5
示例代码
package main
import (
"fmt"
"math"
)
func main() {
/*
接口断言:
方法一:
1.interface := 接口对象.(实际类型) //不安全,会panic()
2.interface,ok := 接口对象.(实际类型) //安全
方法二: switch
switch interface := 接口对象.(type) {
case 实际类型1:
...
case 实际类型2:
...
...
}
*/
var t1 Triangle = Triangle{3, 4, 5}
fmt.Println(t1.peri())
fmt.Println(t1.area())
fmt.Println(t1.a, t1.b, t1.c)
fmt.Println("------------------------")
var c1 Circle = Circle{4}
fmt.Println(c1.peri())
fmt.Println(c1.area())
fmt.Println(c1.radius)
fmt.Println("-----------------------")
var s1 Shape
s1 = t1
fmt.Println(s1.peri())
fmt.Println(s1.area())
fmt.Println("-----------------------")
var s2 Shape
s2 = c1
fmt.Println(s2.peri())
fmt.Println(s2.area())
fmt.Println("----------------------")
testShape(s1)
testShape(s2)
getType(t1)
getType(c1)
getType(s1)
//getType(100)
var t2 *Triangle = &Triangle{3, 4, 2}
fmt.Printf("t2: %T,%p,t2\n", t2, &t2, t2)
getType(t2)
getType1(t2)
getType1(t1)
}
func getType1(s Shape) {
//断言
switch ins := s.(type) {
case Triangle:
fmt.Println("是三角形,三条边是:", ins.a, ins.b, ins.c)
case Circle:
fmt.Println("是圆形,半径是:", ins.peri())
case *Triangle:
fmt.Printf("ins:%T,%p,%p\n", ins, &ins, ins)
fmt.Printf("s:%T,%p,%p\n", s, &s, s)
default:
fmt.Println("我也不知道了")
}
}
func getType(s Shape) {
//断言
if ins, ok := s.(Triangle); ok { // 值传递
fmt.Println("是三角形,三条边是:", ins.a, ins.b, ins.c)
} else if ins, ok := s.(Circle); ok {
fmt.Println("是圆形,半径是:", ins.peri())
} else if ins, ok := s.(*Triangle); ok {
fmt.Printf("ins:%T,%p,%p\n", ins, &ins, ins)
fmt.Printf("s:%T,%p,%p\n", s, &s, s)
} else {
fmt.Println("我也不知道了")
}
}
func testShape(s Shape) {
fmt.Printf("周长: %.2f,面积: %.2f\n", s.peri(), s.area())
}
//1.定义一个接口
type Shape interface {
peri() float64 //形状的周长
area() float64 //形状的面积
}
//2.定义实现类: 三角形
type Triangle struct {
//a float64
//b float64
//c float64
a, b, c float64
}
func (t Triangle) peri() float64 {
return t.a + t.b + t.c
}
func (t Triangle) area() float64 {
p := t.peri() / 2
s := math.Sqrt(p * (p - t.a) * (p - t.b) * (p - t.c))
return s
}
type Circle struct {
radius float64
}
func (c Circle) peri() float64 {
return c.radius * 2 * math.Pi
}
func (c Circle) area() float64 {
return math.Pow(c.radius, 2) * math.Pi
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
上次更新: 2024/04/09, 16:48:42
- 01
- AWS NAT-NetWork-Firwalld配置(一)04-09
- 02
- AWS NAT-NetWork-Firwalld配置(二)04-09
- 03
- kubernetes部署minio对象存储01-18