這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
1 介面的定義與理解
聽 聽 介面是一個自訂類型,它是一組方法的集合。從定義上來看,介面有兩個特點。第一,介面本質是一種自訂類型,因此不要將golang中的介面簡單理解為C++/Java中的介面,後者僅用於聲明方法簽名。第二,介面是一種特殊的自訂類型,其中沒有資料成員,只有方法(也可以為空白)。
聽 聽 介面是完全抽象的,因此不能將其執行個體化。然而,可以建立一個其類型為介面的變數,它可以被賦值為任何滿足該介面類型的實際類型的值。介面的重要特性是:
聽 聽(1)只要某個類型實現了介面要的方法,那麼我們就說該類型實現了此介面。該類型的值可以賦給該介面的變數;
聽 聽(2)作為1的推論,任何類型的值都可以賦值給空介面interface{}
聽 聽 注意:這隻是golang中介面的特性,為非所有類型的特性(介面是一種特殊的類型)。
聽 聽 介面的特性是golang支援鴨子類型的基礎,即“如果它走起來像鴨子,叫起來像鴨子(實現了介面要的方法),它就是一隻鴨子(可以被賦值給介面的值)”。憑藉介面機制和鴨子類型,golang提供了一種游離於類、繼承、模板之外的更加靈活強大的選擇。
2 例子
type聽Exchanger聽interface聽{聽聽聽聽聽聽聽exchange()}聽type聽StringPair聽struct聽{聽聽聽聽聽聽聽first,聽second聽string}聽type聽Point[2]int聽func聽(sp聽*StringPair)聽exchange()聽{聽聽聽聽聽聽聽sp.first,聽sp.second聽=聽sp.second,聽sp.first}聽func聽(p聽*Point)聽exchange()聽{聽聽聽聽聽聽聽p[0],聽p[1]聽=聽p[1],聽p[0]}聽func聽exchangeThese(exchangers聽...Exchanger)聽{聽聽聽聽聽聽聽for聽_,聽exchanger聽:=聽range聽exchangers聽{聽聽聽聽聽聽聽聽聽聽聽聽聽聽exchanger.exchange()聽聽聽聽聽聽聽}}聽func聽main()聽{聽聽聽聽聽聽聽pair1聽:=聽StringPair{"abc","def"}聽聽聽聽聽聽聽pair2聽:=聽StringPair{"ghi","jkl"}聽聽聽聽聽聽聽point聽:=聽Point{5,聽7}聽聽聽聽聽聽聽聽fmt.Println(pair1,聽pair2,聽point)聽聽聽聽聽聽聽pair1.exchange()聽聽聽聽聽聽聽pair2.exchange()聽聽聽聽聽聽聽point.exchange()聽聽聽聽聽聽聽fmt.Println(pair1,聽pair2,聽point)聽聽聽聽聽聽聽聽//聽exchangeThese(pair1,聽pair2)聽//wrong聽聽聽聽聽聽聽exchangeThese(&pair1,聽&pair2)聽聽聽聽聽聽聽fmt.Println(pair1,聽pair2)}
運行結果
聽 聽 在本例中,自訂類型StringPair和Point指標實現了介面Exchanger所需的方法,因此該類型的值可以被賦值給介面的值。
聽 聽 但是,特別注意一點。如果使用exchangeThese(pair1, pair2)會導致編譯錯誤(如),正確寫法應當是exchangeThese(&pair1, &pair2)。這是由於真正滿足介面Exchanger的類型是StringPair指標,而非StringPair。
聽 聽 在golang中,值接收者和指標接收者的方法集是不同的。只是golang會智能地解引用和取引用,使得二者的方法集看上去是一樣的。但是,在調用exchangeThese時,就凸顯出二者的不同了。
本文出自 “說話的白菜” 部落格,謝絕轉載!