11 | 接口

接口是用來(lái)定義行為的類型廊蜒。這些被定義的行為不由接口直接實(shí)現(xiàn),而是通過(guò)方法由用戶自定義類型實(shí)現(xiàn)

  • 斷言
v, ok := varI.(T)

如果轉(zhuǎn)換合法驳庭,v 是 varI 轉(zhuǎn)換到類型 T 的值兼丰,ok 會(huì)是 true;否則 v 是類型 T 的零值笆载,ok 是 false扑馁,也沒(méi)有運(yùn)行時(shí)錯(cuò)誤發(fā)生。

func TestInterface(t *testing.T){
    i := 65
    v,ok := interface{}(i).(int)
    t.Log(v,ok,i)
    //v,ok := interface{}(i).(int8)    //0,false
    //v,ok := interface{}(int8(i)).int(8)  //65,true
    //v,ok := interface{}(i).(string)    //  false
}
  • 值接收者和指針接收者實(shí)現(xiàn)接口
type file interface {
    write(msg string) bool
    read() string
}

type shell struct{
    name string
}
func (s shell) write(msg string) bool {
    fmt.Print("shell write " + msg)
    return true
}

func (s shell) read() string {
    return "hello world"
}

func TestInterface(t *testing.T){
    sFile := shell{"test.sh"}
    val,ok := interface{}(sFile).(file)
    t.Log(val,ok)
    val,ok = interface{}(&sFile).(file)
    t.Log(val,ok)
}
//result: {test.sh} true
// &{test.sh} true
type file interface {
    write(msg string) bool
    read() string
}

type shell struct{
    name string
}
func (s *shell) write(msg string) bool {
    fmt.Print("shell write " + msg)
    return true
}

func (s *shell) read() string {
    return "hello world"
}

func TestInterface(t *testing.T){
    sFile := shell{"test.sh"}
    val,ok := interface{}(sFile).(file)
    t.Log(val,ok)
    val,ok = interface{}(&sFile).(file)
    t.Log(val,ok)
}
//result : <nil> false
// &{test.sh} true

為什么有這個(gè)限制? 下面這句話凉驻,我還不能理解

編譯器并不是總能自動(dòng)獲得一個(gè)值的地址

  • 嵌套接口實(shí)現(xiàn)接口組合
type file interface {
    writeable
    read() string
    execable
}
type writeable interface {
    write(msg string) bool
}
type execable interface{
    exec()
}

type shell struct{
    name string
}
func (s shell) write(msg string) bool {
    fmt.Print("shell write " + msg)
    return true
}
func (s shell) read() string {
    return "hello world"
}
func (s shell) exec() {
    fmt.Print("shell exec")
}
func TestInterface(t *testing.T){
    sFile := shell{"test.sh"}
    val,ok := interface{}(sFile).(execable)
    //val,ok := interface{}(sFile).(writeable)
    t.Log(val,ok,reflect.TypeOf(sFile))
    val,ok = interface{}(sFile).(file)
    t.Log(val,ok,reflect.TypeOf(sFile))
}
//result : {test.sh} true test.shell
//{test.sh} true  test.shell
  • 空接口interface{}
    空接口相當(dāng)于 void *
func TestInterface(t *testing.T){
    var any interface{}
    any = 5
    t.Log(any,reflect.TypeOf(any))
    any = "hello world"
    t.Log(any,reflect.TypeOf(any))
    any = struct{name string}{"fangle"}
    t.Log(any,reflect.TypeOf(any))
    switch tp := any.(type) {
    case int:
        t.Log(tp)
    case string:
        t.Log(tp)
    case bool:
        t.Log(tp)
    default:
        t.Log(tp)
    }
}

/*result :
5 int
hello world string
{fangle} struct { name string }
{fangle}
*/

空接口的內(nèi)部實(shí)現(xiàn)保存了對(duì)象的類型和指針腻要。使用空接口保存一個(gè)數(shù)據(jù)的過(guò)程會(huì)比直接用數(shù)據(jù)對(duì)應(yīng)類型的變量保存稍慢。因此在開(kāi)發(fā)中涝登,應(yīng)在需要的地方使用空接口雄家,而不是在所有地方使用空接口

  • 接口與實(shí)現(xiàn)者的關(guān)系
    值實(shí)現(xiàn)者
type file interface {
    setName(name string)
}
type shell struct{
    name string
}
func (s shell) setName(name string)  {
    s.name = name
}

func TestInterface(t *testing.T){
    sFile := shell{"test.sh"}
    
    var fFace file = sFile
    //sFace.name = "hello" //報(bào)錯(cuò) undifined name
    fFace.setName("hell.sh")
    t.Log(fFace,sFile,reflect.TypeOf(fFace))

    var fFace2 file = &sFile
    fFace2.setName("hello.sh")
    t.Log(fFace2,sFile,reflect.TypeOf(fFace))
}
//result : {test.sh} {test.sh} test.shell
//&{test.sh} {test.sh} test.shell

指針實(shí)現(xiàn)者


type file interface {
    setName(name string)
}
type shell struct{
    name string
}
func (s *shell) setName(name string)  {
    s.name = name
}

func TestInterface(t *testing.T){
    sFile := shell{"test.sh"}
    var fFace file = &sFile
    //var fFace file = sFile  //報(bào)錯(cuò) 接口變量 與 接口 屬性
    fFace.setName("hell.sh")
    t.Log(fFace,sFile,reflect.TypeOf(fFace))
}
//result:&{hell.sh} {hell.sh} 
// *test.shell
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市胀滚,隨后出現(xiàn)的幾起案子趟济,更是在濱河造成了極大的恐慌,老刑警劉巖蛛淋,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咙好,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡褐荷,警方通過(guò)查閱死者的電腦和手機(jī)勾效,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人层宫,你說(shuō)我怎么就攤上這事杨伙。” “怎么了萌腿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵限匣,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我毁菱,道長(zhǎng)米死,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任贮庞,我火速辦了婚禮峦筒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窗慎。我一直安慰自己物喷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布遮斥。 她就那樣靜靜地躺著峦失,像睡著了一般。 火紅的嫁衣襯著肌膚如雪术吗。 梳的紋絲不亂的頭發(fā)上尉辑,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音藐翎,去河邊找鬼材蹬。 笑死实幕,一個(gè)胖子當(dāng)著我的面吹牛吝镣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昆庇,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼末贾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了整吆?” 一聲冷哼從身側(cè)響起拱撵,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎表蝙,沒(méi)想到半個(gè)月后拴测,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡府蛇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年集索,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡务荆,死狀恐怖妆距,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情函匕,我是刑警寧澤娱据,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站盅惜,受9級(jí)特大地震影響中剩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抒寂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一咽安、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蓬推,春花似錦妆棒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至毅糟,卻和暖如春红选,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姆另。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工喇肋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迹辐。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓蝶防,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親明吩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子间学,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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