Go 介面 學習筆記

衣舞晨風發表於2017-08-12

介面interface

  • 介面是一個或多個方法簽名的集合
  • 只要某個型別擁有該介面的所有方法簽名,即算實現該介面,無需顯式宣告實現了哪個介面,這稱為 Structural Typing
  • 介面只有方法宣告,沒有實現,沒有資料欄位
  • 介面可以匿名嵌入其它介面,或嵌入到結構中
  • 將物件賦值給介面時,會發生拷貝,而介面內部儲存的是指向這個複製品的指標,既無法修改複製品的狀態,也無法獲取指標
  • 只有當介面儲存的型別和物件都為nil時,介面才等於nil
  • 介面呼叫不會做receiver的自動轉換
  • 介面同樣支援匿名欄位方法
  • 介面也可實現類似OOP中的多型
  • 空介面可以作為任何型別資料的容器
package main

import (
    "fmt"
)

func main() {
    var a interface{}
    fmt.Println(a == nil)
    var p *int = nil
    a = p
    fmt.Println(a == nil)
}

輸出結果:
這裡寫圖片描述

型別斷言

  • 通過型別斷言的ok pattern可以判斷介面中的資料型別
  • 使用type switch則可針對空介面進行比較全面的型別判斷

介面轉換

  • 可以將擁有超集的介面轉換為子集的介面
package main

import (
    "fmt"
)

//介面巢狀
type Phone interface {
    Name() string
    Connector
}

type Connector interface {
    Connect()
}

type NokiaPhone struct {
    name string
}

func main() {
    var a Phone
    a = NokiaPhone{"phone"}
    a.Connect()
    DisConnect(a)
}

func (np NokiaPhone) Name() string {
    return np.name
}

func (np NokiaPhone) Connect() {
    fmt.Println("Connect")
}

// func DisConnect(phone Phone) {
//  //型別斷言
//  // <目標型別的值>,<布林引數> := <表示式>.( 目標型別 ) // 安全型別斷言
//  if pc, ok := phone.(NokiaPhone); ok {
//      fmt.Println("DisConnect", pc.name)
//      return
//  }
//  fmt.Println("unknown decive")
// }

// //傳入空介面表示,可以傳入任何值
// func DisConnect(phone interface{}) {
//  //型別斷言
//  // <目標型別的值>,<布林引數> := <表示式>.( 目標型別 ) // 安全型別斷言
//  if pc, ok := phone.(NokiaPhone); ok {
//      fmt.Println("DisConnect", pc.name)
//      return
//  }
//  fmt.Println("unknown decive")
// }

func DisConnect(phone interface{}) {
    switch v := phone.(type) {
    case NokiaPhone:
        fmt.Println("DisConnect", v.name)
    default:
        fmt.Println("unknown decive")
    }
}

輸出結果:
這裡寫圖片描述

本文參考整理自:《Go 程式設計基礎》

個人微信公眾號:
這裡寫圖片描述

作者:jiankunking 出處:http://blog.csdn.net/jiankunking

相關文章