1. 程式人生 > >Go入門(六)-interface與反射機制

Go入門(六)-interface與反射機制

interface
interface定義了一系列物件的行為,是一系列方法的組合。
8.1 與java類似,指定義方法,不能實現方法;
8.2 與java不同,Go的interface只能定義方法,不能定義變數;
8.3 與java不同,java的實現類通過關鍵字 implement 實現該interface的方法,Go並不需要特別宣告,只要你實現了這個介面定義的方法,就是實現了該interface;如下例子,human實現了Behavior的介面,又因為human是teacher和student的匿名欄位,所以teacher和student都實現了該介面,professor則過載了sing();
//定義一個interface型別,人類行為,有兩個方法
type Behavior interface {
    sing()
    walk()
}
//定義人類屬性
type human struct {
    name string
    age  int
}
// teacher屬性
type teacher struct {
    human
    salary string
}
// student屬性
type student struct {
    human
    school string
}
//human實現了sing方法
func (h human) sing() {
    fmt.Printf("my name is %s,I am singing\n", h.name)
}
//human實現了walk方法
func (h human) walk() {
    fmt.Printf("my name is %s,I am walking\n", h.name)
}
//professor屬性
type professor struct {
    human
    bachelor string
}
//professor過載sing方法
func (p professor) sing() {
    fmt.Printf("my name is %s,I don't want to sing\n", p.name)
}
func main() {
    Jim := teacher{human{"Jim", 28}, "20000"}
    Lily := student{human{"Lily", 20}, "江南中學"}
    Han := professor{human{"Han", 35}, "PHD"}
    var proxy Behavior
    proxy = Jim
    proxy.sing()
    proxy = Lily
    proxy.sing()
    proxy = Han
    proxy.sing()
}
輸出結果如下:
my name is Jim,I am singing
my name is Lily,I am singing
my name is Han,I don't want to sing
8.4 空interface
8.4.1 空interface不包含任何方法,根據上面的定義,任何型別都實現了該介面!也就是說,定義一個空的interface,它可以指向任何變數,酷不酷?想不想學?

8.4.2 interface的型別檢查
    如果我們想知道這個介面到底是什麼型別,怎麼辦?目前有兩個方法:
8.4.2.1 使用斷言語法:value, ok = element.(T),這裡value就是變數的值,ok是一個bool型別,element是interface變數,T是斷言的型別;

8.4.2.2 使用element.(type)的方式,這個方法只能在switch下使用;


8.4.2.3 嵌入interface
和struct的匿名欄位相似,A struct嵌入了B struct,A就擁有了B的全部屬性,同理,A interface嵌入了B interface,A也擁有了B的method;

8.5 反射
反射就是能檢查程式在執行時的狀態。Go關於反射的方法存放在reflect包,在使用時需要匯入。
8.5.1 reflect.ValueOf(h),得到實際的值,並且可以改變其欄位值;
8.5.2 reflect.TypeOf(h),得到型別的元資料,通過t我們能獲取型別定義裡面的所有元素;
8.5.3 如果需修改value,該struct型別的欄位必須是大寫,前面我們說過,小寫相當於private,是不能通過反射修改的,會報異常:
panic: reflect: reflect.Value.SetString using value obtained using unexported field
詳細的使用方式,請看下面的例子:

輸出結果:
valueOf: {Lucy 22}
type: main.human
kind is human: struct
elem: {Lucy 22}
tag: string
tag: int