typeHumanstruct{namestringageintphonestring}typeStudentstruct{Human//匿名欄位 Humanschoolstringloanfloat32}typeEmployeestruct{Human//匿名欄位 Humancompanystringmoneyfloat32}//Human 物件實現 Sayhi 方法func(h *Human)SayHi(){fmt.Printf("Hi, I am %s you can call me on %s\n",h.name,h.phone)}// Human 物件實現 Sing 方法func(h *Human)Sing(lyricsstring){fmt.Println("La la, la la la, la la la la la...",lyrics)}//Human 物件實現 Guzzle 方法func(h *Human)Guzzle(beerSteinstring){fmt.Println("Guzzle Guzzle Guzzle...",beerStein)}// Employee 過載 Human 的 Sayhi 方法func(e *Employee)SayHi(){fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n",e.name,e.company,e.phone)//此句可以分成多行}//Student 實現 BorrowMoney 方法func(s *Student)BorrowMoney(amountfloat32){s.loan+=amount// (again and again and...)}//Employee 實現 SpendSalary 方法func(e *Employee)SpendSalary(amountfloat32){e.money-=amount// More vodka please!!! Get me through the day!}// 定義 interfacetypeMeninterface{SayHi()Sing(lyricsstring)Guzzle(beerSteinstring)}typeYoungChapinterface{SayHi()Sing(songstring)BorrowMoney(amountfloat32)}typeElderlyGentinterface{SayHi()Sing(songstring)SpendSalary(amountfloat32)}
透過上面的程式碼我們可以知道,interface 可以被任意的物件實現。我們看到上面的 Men interface 被 Human、Student 和 Employee 實現。同理,一個物件可以實現任意多個 interface,例如上面的 Student 實現了 Men 和 YoungChap 兩個 interface。
package main
import "fmt"
type Human struct {
name string
age int
phone string
}
type Student struct {
Human //匿名欄位
school string
loan float32
}
type Employee struct {
Human //匿名欄位
company string
money float32
}
//Human 實現 SayHi 方法
func (h Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
//Human 實現 Sing 方法
func (h Human) Sing(lyrics string) {
fmt.Println("La la la la...", lyrics)
}
//Employee 過載 Human 的 SayHi 方法
func (e Employee) SayHi() {
fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
e.company, e.phone)
}
// Interface Men 被 Human,Student 和 Employee 實現
// 因為這三個型別都實現了這兩個方法
type Men interface {
SayHi()
Sing(lyrics string)
}
func main() {
mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}
paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}
sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}
tom := Employee{Human{"Tom", 37, "222-444-XXX"}, "Things Ltd.", 5000}
//定義 Men 型別的變數 i
var i Men
//i 能儲存 Student
i = mike
fmt.Println("This is Mike, a Student:")
i.SayHi()
i.Sing("November rain")
//i 也能儲存 Employee
i = tom
fmt.Println("This is tom, an Employee:")
i.SayHi()
i.Sing("Born to be wild")
//定義了 slice Men
fmt.Println("Let's use a slice of Men and see what happens")
x := make([]Men, 3)
//這三個都是不同型別的元素,但是他們實現了 interface 同一個介面
x[0], x[1], x[2] = paul, sam, mike
for _, value := range x{
value.SayHi()
}
}
// 定義 a 為空介面
var a interface{}
var i int = 5
s := "Hello world"
// a 可以儲存任意型別的數值
a = i
a = s
type Stringer interface {
String() string
}
package main
import (
"fmt"
"strconv"
)
type Human struct {
name string
age int
phone string
}
// 透過這個方法 Human 實現了 fmt.Stringer
func (h Human) String() string {
return "❰"+h.name+" - "+strconv.Itoa(h.age)+" years - ✆ " +h.phone+"❱"
}
func main() {
Bob := Human{"Bob", 39, "000-7777-XXX"}
fmt.Println("This Human is : ", Bob)
}
//實現同樣的功能
fmt.Println("The biggest one is", boxes.BiggestsColor().String())
fmt.Println("The biggest one is", boxes.BiggestsColor())
package main
import (
"fmt"
"strconv"
)
type Element interface{}
type List [] Element
type Person struct {
name string
age int
}
//定義了 String 方法,實現了 fmt.Stringer
func (p Person) String() string {
return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)"
}
func main() {
list := make(List, 3)
list[0] = 1 // an int
list[1] = "Hello" // a string
list[2] = Person{"Dennis", 70}
for index, element := range list {
if value, ok := element.(int); ok {
fmt.Printf("list[%d] is an int and its value is %d\n", index, value)
} else if value, ok := element.(string); ok {
fmt.Printf("list[%d] is a string and its value is %s\n", index, value)
} else if value, ok := element.(Person); ok {
fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)
} else {
fmt.Printf("list[%d] is of a different type\n", index)
}
}
}
是不是很簡單啊,同時你是否注意到了多個 if 裡面,還記得我前面介紹流程時講過,if 裡面允許初始化變數。
也許你注意到了,我們斷言的型別越多,那麼 if else 也就越多,所以才引出了下面要介紹的 switch。
package main
import (
"fmt"
"strconv"
)
type Element interface{}
type List [] Element
type Person struct {
name string
age int
}
//列印
func (p Person) String() string {
return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)"
}
func main() {
list := make(List, 3)
list[0] = 1 //an int
list[1] = "Hello" //a string
list[2] = Person{"Dennis", 70}
for index, element := range list{
switch value := element.(type) {
case int:
fmt.Printf("list[%d] is an int and its value is %d\n", index, value)
case string:
fmt.Printf("list[%d] is a string and its value is %s\n", index, value)
case Person:
fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)
default:
fmt.Println("list[%d] is of a different type", index)
}
}
}
type Interface interface {
sort.Interface //嵌入欄位 sort.Interface
Push(x interface{}) //a Push method to push elements into the heap
Pop() interface{} //a Pop elements that pops elements from the heap
}
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less returns whether the element with index i should sort
// before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
// io.ReadWriter
type ReadWriter interface {
Reader
Writer
}
t := reflect.TypeOf(i) //得到型別的 Meta 資料,透過 t 我們能取得型別定義裡面的所有元素
v := reflect.ValueOf(i) //得到實際的值,透過 v 我們取得儲存在裡面的值,還可以去改變值
tag := t.Elem().Field(0).Tag //取得定義在 struct 裡面的標籤
name := v.Elem().Field(0).String() //取得儲存在第一個欄位裡面的值
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type())
fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
fmt.Println("value:", v.Float())
var x float64 = 3.4
v := reflect.ValueOf(x)
v.SetFloat(7.1)
var x float64 = 3.4
p := reflect.ValueOf(&x)
v := p.Elem()
v.SetFloat(7.1)