用interfce定義行為(範例)
範例
已經有收藏很多文章LINK介紹如何定義了,這邊直接進入練習如何定義行為的幾種差異。
範例程式
定義一般類型(string)與其方法
定義Stringer 介面
定義person類型與其方法與定義Person 介面:
// 綁定的NewXXX方法(xxx) interfacr{
// ....xxxxx
// return T{XXX:xxx...} //struct
//}
func NewPersonI(name string) Person { //回傳是一個Person介面
return person{Name: name} //會檢查對象struct person是否具有Person(interface) 的方法
}
//對象struct 實作方法
func (s person) MyName() string {
return s.Name
}
定義SuperMan 類型與其方法與定義SuperMan 介面
定義一個方法showTypeAndDoTheirFunc(any interface{})可以接受任何類型
類型斷言判斷效果與執行各類型的方法
Main宣告介面或是類型的方式不同顯示
package main
import (
"fmt"
"strconv"
)
// 定義str類型與其方法
type str string
func (s str) String() string {
return string(s)
}
// 定義Stringer interface
type Stringer interface {
String() string
}
// person 與其方法
type person struct {
Name string
}
func (s person) String() string {
return s.Name
}
func (s person) MyName() string {
return s.Name
}
// New person對象
func NewPerson(name string) person {
return person{Name: name} //返回person對象
}
// 宣告 person介面
func NewPersonI(name string) Person { //回傳是一個介面
return person{Name: name} //會檢查對象person是否具有Person(interface) 的方法
}
type Person interface {
String() string
MyName() string
}
func showTypeAndDoTheirFunc(any interface{}) string {
// if v, ok := any.(Person); ok { //可以這樣寫 或是寫進switch case
// fmt.Printf("It is Person.(type) %T \n", v)
// return v.MyName()
// }
// if v, ok := any.(Stringer); ok {
// fmt.Printf("It is Stringer.(type) %T \n", v)
// return v.String()
// }
switch v := any.(type) {
case SuperMan:
fmt.Printf("It is SuperMan.(type) %T \n", v)
return v.MyName()
case Person:
fmt.Printf("It is Person.(type) %T \n", v)
return v.MyName()
case Stringer:
fmt.Printf("It is Stringer.(type) %T \n", v) //Stringer擁有Person其中一樣方法,不能寫在Person前
return v.String()
case int:
fmt.Printf("It is int.(type) %T \n", v)
return strconv.Itoa(v)
case float64:
fmt.Printf("It is float64.(type) %T \n", v)
return strconv.FormatFloat(v, 'g', -1, 64)
}
return "???"
}
func main() {
var ex2 float64 = 0.1
fmt.Println(showTypeAndDoTheirFunc(ex2))
fmt.Printf("-------\n")
var ex3 Stringer = str("1")
fmt.Println(showTypeAndDoTheirFunc(ex3))
fmt.Printf("-------\n")
var p1 Person = person{Name: "YU_I"} //使用介面
fmt.Println(showTypeAndDoTheirFunc(p1))
var p2 = NewPersonI("ALICE_I") //利用func New來指定介面寫法
fmt.Println(showTypeAndDoTheirFunc(p2))
fmt.Printf("-------\n")
var p4 = person{Name: "YU"} //不使用介面
fmt.Println(showTypeAndDoTheirFunc(p4))
var p3 = NewPerson("ALICE") //利用func New來指定寫法
fmt.Println(showTypeAndDoTheirFunc(p3))
fmt.Printf("-------\n")
var sm1 = NewSuperManI("xMan") //利用func New來指定介面寫法
fmt.Println(showTypeAndDoTheirFunc(sm1))
fmt.Println("MyName:", sm1.MyName()) //操作介面方法
fmt.Printf("-------\n")
}
func NewSuperManI(name string) SuperMan { //回傳是一個介面
return superMan{Name: name} //會檢查對象person是否具有Person(interface) 的方法
}
type SuperMan interface {
Fly() string
MyName() string
}
type superMan struct {
Name string
}
func (s superMan) Fly() string {
return s.Name
}
func (s superMan) MyName() string {
return s.Name
}
補充
你可以使用介面去做物件的操作,NewXXX 回傳的是一個介面,再用這接口去做操作.
Last updated