在 Go 語言中的類型是可以直接內嵌到結構體中的,可以看作是一個沒有屬性名的屬性。同時接口中也可以內嵌接口,并且只能內嵌接口。本文就來講解以下 Go 語言如何使用內嵌類型。
1. 結構體內嵌類型
結構體中內嵌類型在開發中用的并不多,這只是一個延伸特性。意味著結構體在定義屬性字段的時候可以只寫類型,不寫屬性名,但是一個類型只能寫一個,不然結構體會無法識別你調用的時候使用的是哪個字段,這種只寫類型不寫屬性名的屬性被稱為匿名字段。
代碼示例:
package main
import "fmt"
type Student struct {
Name string
Age int
int
}
func newStudent(name string, age int) Student {
return Student{Name: name, Age: age, int: 10}
}
func main() {
stu := newStudent("Codey", 18)
fmt.Println("匿名字段的值:", stu.int)
}
- 第 8 行:結構體中內嵌了一個int類型;
- 第 12 行:給匿名字段賦值的時候直接使用其字段類型即可;
- 第 16 行:打印匿名字段的值。
執行結果:
2. 結構體內嵌結構體
結構體內嵌結構體是用的最多的一種內嵌方式。它有點類似于面向對向語言中的繼承,但是面向對象的設計原則中最好不要有多繼承。甚至于 java 這個面向對象語言的老大哥,直接就是不允許多繼承的。所以 Go 語言中的內嵌結構體更好理解為組合。
代碼示例:
package main
import "fmt"
type Callable struct{}
func (c Callable) Call() {
fmt.Println("can call")
}
type Photographic struct{}
func (p Photographic) Photograph() {
fmt.Println("can take photos")
}
type Moblie struct {
Callable
Photographic
}
type Pad struct {
Photographic
}
func main() {
var m Moblie
fmt.Println("Moblie Function:")
m.Call()
m.Photograph()
var p Pad
fmt.Println("Pad Function:")
p.Photograph()
}
- 第 5~15 行:定義了兩個功能結構體:打電話和拍照;
- 第 17~20 行:用打電話和拍照兩個功能結構體,組合成為手機結構體;
- 第 22~24 行:用拍照功能結構體,組合成為平板電腦結構體;
- 第 26~34 行:初始化兩個結構體,并打印它們的功能。
執行結果:
3. 接口內嵌接口
接口內嵌接口也是一個非常實用的特性,可以使用這個功能來使同一個結構體,放在不同的接口中,而能使用的功能不同。常用的權限控制,對一個相同的數據結構,但是能操作的權限可以用接口分開。
代碼示例:
package main
import "fmt"
type Reader interface {
Read()
}
type Writer interface {
Write()
}
type OnlyReader interface {
Reader
}
type ReaderAndWriter interface {
Reader
Writer
}
type file struct{}
func (f file) Read() {
fmt.Println("Read something")
}
func (f file) Write() {
fmt.Println("Write something")
}
func main() {
f := file{}
var rAndW ReaderAndWriter
rAndW = f
rAndW.Read()
rAndW.Write()
var onlyR OnlyReader
onlyR = f
onlyR.Read()
}
- 第 13~15 行:內嵌一個讀接口到只讀接口中;
- 第 17~20 行:內嵌讀和寫的接口到讀寫接口中;
- 第 22~30 行:定義一個接口體實現讀接口和寫接口。
執行結果:
4. 小結
本文介紹了結構體和接口的內嵌類型。其中結構體內嵌結構體和接口內嵌接口最為常用。需要注意的是接口只能內嵌接口,不可內嵌其它類型。