Golang - interface


定義

接口是一種抽象的類型
理解爲關聯更加準確
接口的實現: 一個對象只要全部實現了接口中的方法, 就是實現了這個接口
給接口命名時, 通常在單詞後加"er"


示例

package main

import "fmt"

// go語言中, 接口(interface)是一種抽象的類型, 理解爲協議或約定更加準確

// Cat 貓
type Cat struct{}

// Dog 狗
type Dog struct{}

// Say 喵喵喵
func (c Cat) Say() string {
	return "喵喵喵"
}

// Say 汪汪汪
func (d Dog) Say() string {
	return "汪汪汪"
}

// Sayer 所有會說話的(有Say方法的)
type Sayer interface {
	Say() string // 需要實現的方法名(參數) 返回值
}

func main() {
	c := Cat{}
	d := Dog{}

	var animallist []Sayer
	animallist = append(animallist, c, d)

	for _, v := range animallist {
		fmt.Println(v.Say())
	}
}


接口的嵌套

type speaker interface {
	speak()
}

type mover interface {
	move()
}

// animal接口中嵌套了speaker接口和mover接口, 也就是說實現了animal接口必須同時實現speaker和mover
type animaler interface {
	speaker
	mover
}

空接口

沒有定義任何方法的接口, 因此, 任何類型都實現了空接口
空接口類型的變量, 可以存儲任意類型的變量

package main

import (
	"fmt"
	"time"
)

// 空interface

type cat struct{}


func main() {
	var x interface{}
	x = 10
	fmt.Printf("%T, 值爲%v\n", x, x)
	
	x = "10"
	fmt.Printf("%T, 值爲%v\n", x, x)

	x = time.Second
	fmt.Printf("%T, 值爲%v\n", x, x)

	x = cat{}
	fmt.Printf("%T, 值爲%v\n", x, x)
	
	x = "哈哈"
	// 注意! 此時x爲interface類型, 所以&x類型爲*interface{}
	fmt.Printf("%T, 值爲%v\n", x, x) 
}


類型斷言

  • if
func showType(x interface{}) { // 作爲參數可以接收一切類型
	// 因爲這個函數可以接收任意類型的變量
	// 類型斷言
	v, ok := x.(int)
	if !ok {
		// 說明不是int
	} else {
		fmt.Println("是int類型, 值爲:", v)
	}
}
  • switch
func showType(x interface{}) { // 作爲參數可以接收一切類型
	// fmt.Printf("Type: %T, 值: %v\n", x, x)

	// 因爲這個函數可以接收任意類型的變量
	// 類型斷言
	switch v := x.(type) {
	case string:
		fmt.Printf("類型爲string, 值爲%v\n", v)
	case int:
		fmt.Printf("類型爲int, 值爲%v\n", v)
	case bool:
		fmt.Printf("類型爲bool, 值爲%v\n", v)
	case *string:
		fmt.Printf("類型爲string指針, 值爲%v\n", v)
	case cat:
		fmt.Printf("類型爲cat結構體, 值爲%v\n", v)
	default:
		fmt.Println("不是string, int, bool")
	}
}


值接收者和指針接收者實現接口的區別

值接收者

package main

import "fmt"

// 實現接口時, 使用指針接收者和值接收者的區別

type animal interface {
	move() string
}

type cat struct {
	name string
}

// 值接收者
func (c cat) move() string { // 由值接收者實現move方法
	return "我能動"
}

func main() {
	var x animal
	
	hh := cat{name: "花花"} // 實例化一個cat類型
	x = hh // 由於是值接受者實現的move方法, 所以hh實現了接口
	 
	tom := &cat{"tom"} // 實例化, 並將指針賦值給tom
	x = tom // 通過go語言語法糖內部實現, 將tom轉換成*tom
	
	fmt.Println(x.move())
	fmt.Println(tom.move()) // (*tom).move()
}


指針接收者

package main

import "fmt"

// 實現接口時, 使用指針接收者和值接收者的區別

type animal interface {
	// speak() string
	move() string
}

type cat struct {
	name string
}

func (c *cat) move() string {
	return "我能動"
}

func main() {
	var x animal

	tom := &cat{name: "tom"} // 實例化, 並將指針賦值給tom
	x = tom                  // 實現animal接口的是*cat類型, tom此時爲cat類型指針

	fmt.Println(x.move())
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章