Go的 structs 是一種包含一堆named fields的型別, 可以很方便的用來整合一堆相關的資料, 例如:
type person struct {
name String
age int
}
上面宣告了一個叫作具有name
和age
兩個fields的, 叫作pperson
的struct type。
我們利用以下的方法建立新的person struct:
person{"Bob", 20}
person{name: "Alice", age: 30}
person{name: "Fred"}
上述第3種方式, 會把沒有初始化的值賦予 zero-value。
我們也可以利用 &
prefix來產生(yield) 指向這個struct的指標:
&person{name: "Ann", age: 40}
利用.
(dot)來存取struct的field:
s := person{name: "Sean", age: 50}
fmt.Println(s.name)
Struct是可以被修改的(mutable):
sp := &s
fmt.Println(sp.age)
sp.age = 51
fmt.Println(sp.age)
最後的結果就會印出51。
Go沒有classes。 不過, structs + methods 就像classes。
不過我們可以在struct type裏面定義function, 叫作 methods。
以下我們建立了有一個 *rect的receiver type的method:
type rect struct {
width, height int
}
func (r *rect) area() int {
return r.width * r.height
}
Method可以定義接收pointer或是value type, 例如以下就是value receiver:
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
呼叫方式如下:
r := rect{width: 10, height: 5}
fmt.Println("area: ", r.area())
fmt.Println("perim:", r.perim())
Go會幫我們處理value以及pointer之間的轉換, 不過如果要避免method call都要拷貝額外的參數值, 或是想要更動struct的內容的時候, 可以考慮使用 pointer receiver type。
Interface type就是定義一組 methods的集合。
例如我們定義一個幾何圖形的interface:
type geomentry interface {
area() float64
perim() float64
}
再來定義兩個幾何圖形: rect矩型 和 circle圓形兩種types:
type rect struct {
width, height float64
}
type circle struct {
radius float64
}
我們可以分別實作rect和circle兩種types的interfaces, 例如rect的:
func (r rect) area() float64 {
return r.width * r.height
}
func (r rect) perim() float64 {
return 2*r.width + 2*r.height
}
實作circle type的interface:
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
return 2 * math.Pi * c.radius
}
Go沒有implement
這樣的keyword, Go會自動判定該型別是否有完全實作整個interface所定義的methods。
假設我們的function傳入的參數是interface type, 那麼只要是實作這個interface的type都可以使用這個function:
func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
fmt.Println(g.perim())
}
例如:
r := rect{width: 3, height: 4}
c := circle{radius: 5}
measure(r)
measure(c)
Interface就代表兩個事情:
Interface{}
type表示 empty interface, 一個沒有任何method的interface。
例如:
func DoSomething(v interface{}) {
// ...
}
表示我們可以傳任何type到Dosomething函式中, 但是v原來的type會被轉換成interface{}
type。
在看API的時候會常常看到empty interface:
func Println(a ...interface{}) (n int, err error) {
return Fprintln(os.Stdout, a...)
}
...interface{}
表示可以餵入任意數量與任意型別的參數。
how to use interface in go - by jordan orelli
what is the meaning of interface in golang
這系列筆記文章都來自於以下局部翻譯或整理:
An introduction to programming in Go