Go語言中介面相關知識點彙總
最近公司有專案需要使用go語言來重構以前用php編寫的專案,我其實對go沒啥興趣,但是為了生活,只能啃起來了,這裡借`狂神`的名言,與君共勉吧!
---------
只要學不死,就往死裡學! ----狂神
---------
介面的定義
在支援面向物件的語言裡,基本上都有介面概念, 介面的定義:它是定義一個物件的行為,具體的實現細節,由物件本身確定
介面的關鍵字:interface
介面的宣告與實現
//宣告 一個介面
type Person interface{
eat()
}
//建立一個結構體,模擬一個類,在go語言中沒有class的概念!
type Man struct{
name string
}
//這裡是Man型別實現了接口裡的方法eat(),也就可以說它實現了介面(這裡需要全部實現了接口裡的方法,才是實現了介面)
func (p Man) eat() {
fmt.Println(p.name,",有好吃的嗎?")
}
//實現
func main() {
var v Person
man :=Man{name: "test"}
//這裡注意,由於man是實現了Person的介面,要不是會報錯的
v=man
v.eat()
}
總結
//1.go裡面沒有implement關鍵字
//2.只要是型別實現了接口裡的所有方法,就可以說是它是實現了這個介面
實際應用
//舉個實際中的例子,在專案裡,我們有個一個針對不同等級的會員,積會計算的方式會有些不同,這個場景是非常合適用介面來解決的,
//定義一個計算積分的介面,不同的等級會員都實現自己的計算方法就可以
//定義一個計算積分的介面
type CalcPoint interface{
calc() float64
}
//定義一個普通會員的結構體
type ComMember struct{
name string
score float64
}
func (c ComMember) calc() float64 {
return c.score+10
}
//定義一個高階會員的結構體
type GoldMember struct{
name string
score float64
}
func (g GoldMember) calc() float64 {
return g.score+20
}
//這裡就簡化了,這裡做個無用功能吧,就是計算下,所有人的積分總和是多少
//定義一個接收calcPoint型別引數的 函式
func getTotalScore(members []CalcPoint) {
total :=0.00
for _, member :=range members {
total=total+member.calc()
}
fmt.Println("總積分",total)
}
func main() {
//建立一個普通會員
member1 :=ComMember{
name: "ton",
score: 78,
}
//建立一個高階會員
member2 :=GoldMember{
name: "uzi",
score: 89,
}
members :=[]CalcPoint{member1,member2}
getTotalScore(members) // 返回值197
}
空介面
空介面:沒有包含方法的介面,所以在go語言中,所有的型別都是空介面
表示方法:interface{}
型別斷言
//型別斷言
i.(T) //介面i的具體型別T
//
func main(){
var s interface{}="abc"
a,ok :=s.(string)//a=>值,ok,如果斷言成功,返回true,否則返回false
fmt.Println(a,ok)
}
//使用switch case進行型別選擇
func findType(i interface{}){
switch i.(type){ //注意這裡i.(type)
case int:
fmt.Println("int")
case string:
fmt.Println("string")
case float64:
fmt.Println("float64")
default:
fmt.Println("沒有找到")
}
}
實現介面的方法:指標接收者和值接收者
結論
如果接收者型別為指標,則接收者的值只能是指標
如果接收者型別為值型別,則接收者的值可以是指標或者是值
程式碼說明
package main
import "fmt"
type notifier interface{
notify()
}
func sentNotify(n notifier) {
n.notify()
}
type User struct{
name string
}
func (u *User) notify() {//這裡的值是指標型別接收者
fmt.Println("user中的notify")
}
//如果這個值是值型別接收者時,在呼叫這個sentNotify()函式傳引數時,可以是指標型別或者是值型別都可以
func (u User) notify() {//這裡的值是指標型別接收者
fmt.Println("user中的notify")
}
func main() {
u:=User{
name: "abc",
}
//sentNotify(u)//這裡是報錯的 cannot use u (type User) as type notifier in argument to sentNotify:
// User does not implement notifier (notify method has pointer receiver)
//這意思也是說 這個介面方法接收指標型別的值,你給一個值型別的引數是不可以的
//需要傳指標型別的值
sentNotify(&u)
}