Go學(xué)習(xí)之路(九)接口

Go的接口和其它語言中的方法不一樣,它是以使用者為主,先定義接口中需要的方法,再去實現(xiàn)接口中的這些方法

type Inface interface{
  Say(msg string)string
  Name()string
}

我先定義一個接口,我想在這個接口中需要一個函數(shù),我要往這個函數(shù)里面?zhèn)饕粋€string的值,然后返回一個string的值

type Dog struct{
  Name string
}
type Cat struct{
  Name string
}

定義兩個接口變量,一個狗,一個貓

// 這里的 Dog 結(jié)構(gòu)體可以使用指針,也可以使用值,使用值可以接收指針和值兩種,如果使用指針,那就只能接收指針
func (d *Dog) Say(msg string) string{
  return fmt.Sprintf("%s,%s",d.Name,msg)
}
func (c *Cat) Say(msg string) string{
  return fmt.Sprintf("%s,%s",c.Name,msg)
}

這里是實現(xiàn)接口方法

func main(){
  var inface Inface
  cat:=Cat{"藍貓"}
  inface=&cat
  ca:=inface.Say("你們好")
  dog:=Dog{"金毛"}
  inface=&dog
  do:=inface.Say("Hello")
  fmt.Println(ca)
  fmt.Println(do)
}

結(jié)果

藍貓,你們好
金毛,Hello

例子2
文件目錄

  • retriever
    • real
      • retriever.go
    • main.go
// 這個是main.go
package main
import (
    "fmt"
    "retriever/real"

)
type Retriever interface{
  Get(url string) string
}
type download(r Retriever) string{
  return r.Get("http://baidu.com")
}

func main(){
  var r Retriever
  r = real.Retriever{}
  fmt.Println(download(r))
}

retriever.go 文件

package real
import (
    "net/http"
    "net/http/httputil"
    "time"
)
type Retriever struct{
}
// 這里的 r Retriever 是 Retriever 這個結(jié)構(gòu)體
// 實現(xiàn)接口 Retriever 中的Get方法
func (r Retriever) Get(url string) string{
  resp,err := http.Get(url)
  if err != nil{
    panic(err)
  }
  result,err := httputil.DumpResponse(resp,true)
  resp.Body.Close()
  if err != nil{
    panic(err)
  }
  return string(result)
}

Go 接口最佳實踐(接口組合)

  • 傾向于使用小的接口定義, 很多接口只包含一個方法
  • 較大的接口定義,可以由多個小接口定義組合而成
  • 只依賴于必要功能的最小接口
    例子
// 最小接口
type Reader interface{
  Read(p []byte) (n int, err error)
}
type Writer interface {
  Write(p []byte) (n int, err error)
}
// 大接口,由多個小接口組合
type ReadWriter interface {
  Reader
  Writer
}
// 只用小接口的時候就不用麻煩的調(diào)用其它接口
func StoreData(reader Reader) err{
  ...
}

例子2

文件目錄

  • retriever
    • mock
      • mockretriever.go
    • main.go
package main
type Retriever interface{
  Get(url string) string
}
type Poster interface{
  Post(url string, from map[string] string) string
}
func download(r Retriever)string{
  return r.Get("http://baidu.com")
}
func post(poster Poster){
  poster.Post("http://baidu.com",map[string]string{
    "name":"熊貓拍板磚",
    "contents":"這是我自己定義的命名",
  })
}
type RetrieverPoster interface{
  Retriever
  Poster
}

func session(r RetrieverPoster) string{
  r.Post("http://baidu.com", map[string]string{
    "contents":"another faked aliyun.com",
  })
  r.Get("http://baidu.com")
}

func main(){
  var r Retriever 
  retriever := &mock.Retriever{"this is a fake 熊貓拍板磚"}
  r = retriever
  fmt.Println(download(r))
  fmt.Println(session(retriever))
}
package mock
type Retriever struct{
  Contents string
}

func (r *Retriever) Get(string) string{
  return r.Contents
}
func (r *Retriever) Post(url string, map[string]string)string{
  r.Contents=from["contents"]
  return "ok"
  
}

結(jié)果

this is a fake 熊貓拍板磚
another faked aliyun.com

空接口與斷言

  • 1.空接口可以表示任何類型
    1. 通過斷言來將空接口取出指定的類型
      v,ok :=p.(int) // ok=true 時為取出成功
      p.(int) 這里的p 空接口 int 是要斷言的類型
package main

func DoSomething(r interface{}) interface{}{
  switch v:=r{
    case int:
      fmt.Print("int  ")
      return v
    case string:
      fmt.Print("string ")
      return v
  }
}

type slice []interface{}

func main(){
  var b slice
  b=append(b,1)
  b=append(b,"zhangsan")
  b=append(b,2)
  b=append(b,"lisi")
  // 第一種斷言方法
  for _,v:=range b{
    fmt.Println(DoSomething(v))
  }
  // 第二種斷言方法
  for _,v := range b{
    if j,ok :=v.(int);ok{
      fmt.Println(j)
    }
  }
}

結(jié)果

// 第一種結(jié)果
int 1
string zhangsan
int 2
string lisi
// 第二種結(jié)果
1
2
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衣盾,更是在濱河造成了極大的恐慌抛计,老刑警劉巖卓嫂,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓮具,死亡現(xiàn)場離奇詭異槽袄,居然都是意外死亡给僵,警方通過查閱死者的電腦和手機毫捣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帝际,“玉大人蔓同,你說我怎么就攤上這事《拙鳎” “怎么了斑粱?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脯爪。 經(jīng)常有香客問我则北,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮熟妓,結(jié)果婚禮上臀规,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好炫贤,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布爷恳。 她就那樣靜靜地躺著方篮,像睡著了一般名秀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上藕溅,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天匕得,我揣著相機與錄音,去河邊找鬼蜈垮。 笑死耗跛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的攒发。 我是一名探鬼主播调塌,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惠猿!你這毒婦竟也來了羔砾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤偶妖,失蹤者是張志新(化名)和其女友劉穎姜凄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趾访,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡态秧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了扼鞋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片申鱼。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖云头,靈堂內(nèi)的尸體忽然破棺而出捐友,到底是詐尸還是另有隱情,我是刑警寧澤溃槐,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布匣砖,位于F島的核電站,受9級特大地震影響昏滴,放射性物質(zhì)發(fā)生泄漏猴鲫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一谣殊、第九天 我趴在偏房一處隱蔽的房頂上張望拂共。 院中可真熱鬧,春花似錦蟹倾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽肌厨。三九已至,卻和暖如春豁陆,著一層夾襖步出監(jiān)牢的瞬間柑爸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工盒音, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留表鳍,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓祥诽,卻偏偏與公主長得像譬圣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子雄坪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容