接口嵌套 (接口繼承)
一個接口可以嵌套在另外的接口,如下所示
範例
1 | package main |
- 一種接口類型可放到其他接口類型中
- 若要實現
File
接口,則ReadWrite
及Lock
接口的所有方法及close()方法都必須實現 - 類似結構體嵌套匿名結構體
result
1 | Write.... |
類型斷言 (類型轉換)
- 由於接口是一般類型,並不知道具體類型
- 任何類型只要滿足a接口內所有的方法,該類型亦為a接口類型
- 再調用函數時,參數接受a接口類型時,並不知道傳參進來的a接口指向的是何種類型的實例(如上範例)
- 要是接口指向的是非期望的類型需進行類型轉換再操作
- 此時便需做類型斷言
如要轉成具體類型可採用以下方式進行轉換
不安全的類型斷言
1 | var t int |
範例
1 | package main |
[1] 要是傳進來的參數不為int
類型時,斷言為int
將會panic
,因此需要安全的類型斷言
安全的類型斷言
在進行斷言之前會先檢查是否能轉換
1 | var t int |
範例
1 | package main |
判斷傳參的類型(利用switch斷言)
使用switch
判斷傳入參數的類型
1 | package main |
- 須注意
x.(type)
這樣的用法,用來作類型斷言的判斷非常好用 - 也可用來判斷自定義的類型,如
struct
、指針類型等
result
1 | number 0 type is string |
tips
- 類型斷言不一定是只拿某個接口類型的變量判斷是否能轉成其他類型
- 其他類型的變量也能拿來判斷是否實現了接口 (比較少用)
practice
- 實現一個可存放任何類型data的鏈表
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
56package main
import "fmt"
type data_save struct {
data interface{}
next *data_save
}
type record_pointer struct {
Head *data_save
Tail *data_save
}
func (self *record_pointer)InsertHead_CreateNode(data interface{}){
Node := &data_save{}
Node.data = data
if self.Head == nil && self.Tail ==nil {
self.Head = Node
self.Tail = Node
return
}
Node.next = self.Head
self.Head = Node
}
func (self *record_pointer)InsertTail_CreateNode(data interface{}){
Node := &data_save{}
Node.data = data
if self.Head == nil && self.Tail ==nil {
self.Head = Node
self.Tail = Node
return
}
self.Tail.next = Node
self.Tail = Node
}
func (self *record_pointer)view(){
var p *data_save = self.Head
for p != nil {
fmt.Println(*p)
p = p.next
}
}
func main(){
var a record_pointer
for i:=0;i<10;i++{
a.InsertTail_CreateNode(i)
}
a.view()
} - 只要存放的data接受空接口類型(
interface{}
),就能存放任何類型的變量
result
1 | {0 0xc04205a400} |