Golang 函數 方法 介面的簡單介紹
函數
函數是基本的程式碼塊,通常我們會將一個功能封裝成一個函數,方便我們調用,同時避免程式碼臃腫複雜。
函數的基本格式
func TestFunc(a int, b string) (int, string) {
// body
}
函數基本在每種語言都經常使用,所以感覺沒什麼記錄的。
方法
方法與對象綁定,簡單的來講只是將對象傳遞給函數使其成為一種特殊(只屬於該對象)的函數,因為Golang
是沒有類
這個概念(在Golang
里,結構體
是類
的簡化版),所以也可以將方法理解為類的成員函數
,但需要注意的是,在Golang
里幾乎所有數據類型都可以與方法綁定。
方法的基本格式
func (a objectType) TestMethod(a int, b string) (int, string) {
// body
}
先定一個結構體
type Test1 struct {
aaa int
bbb int
}
func (t Test1) String() string {
res := fmt.Sprintf("aaa:%d, bbb:%d", t.aaa, t.bbb)
return res
}
指針或者值作為綁定對象的區別
指針和值都可以綁定方法,並且我們不需要手動區分,這是因為Golang
會自動解引用。
只讀對象的內部變數
指針和值是沒有區別的,下面的程式碼分別使用了值和指針綁定:
func (t *Test1) Sum() int {
return t.aaa + t.bbb
}
func (t Test1) Mul() int {
return t.aaa * t.bbb
}
然後我們定義一個對象來分別調用上面的兩個方法:
ttt := Test1{aaa: 5, bbb: 2}
fmt.Println("Sum:", ttt.Sum())
fmt.Println("Mul:", ttt.Mul())
// output:
// Sum: 7
// Mul: 10
修改對象的內部變數
如果需要修改對象的內部變數,就必須在對象的指針類型上定義該方法,下面的程式碼分別使用了值和指針綁定:
func (t *Test1) modifyByAddr(a int) {
t.aaa = a
}
func (t Test1) modifyByValue(a int) {
t.aaa = a
}
然後我們定義一個對象來分別調用上面的兩個方法:
fmt.Println("old value:", ttt)
ttt.modifyByValue(222)
fmt.Println("modifyByValue:", ttt)
ttt.modifyByAddr(111)
fmt.Println("modifyByAddr:", ttt)
// output
// old value: aaa:5, bbb:2
// modifyByValue: aaa:5, bbb:2
// modifyByAddr: aaa:111, bbb:2
函數與方法的區別
通過上面的例子來說明
函數
將變數當做參數傳入Test1Sum(ttt)
方法
是被變數調用ttt.Mul()
和ttt.Sum()
介面
介面定義了一組方法,但這些方法並沒有實現,使用該介面的前提是對象實現了介面內部的方法,這裡需要特別注意,對象必須實現介面里的所以方法,或者會報錯。
下面我們定義了一個介面,包含兩個方法,其中modify(int, int)
我們沒有在結構體Test1
里實現。
type TestInterface interface {
Sum() int
modify(int, int)
}
我們將對象賦給介面的時候就會報錯,程式碼如下:
ttt := new(Test1)
ttt.aaa = 5
ttt.bbb = 2
var test1Face TestInterface
test1Face = ttt
這時候就會報錯如下資訊:
src/test.go:44:14: cannot use ttt (variable of type Test1) as type TestInterface in assignment:
Test1 does not implement TestInterface (Sum method has pointer receiver)
完整程式碼
package main
import "fmt"
type TestInterface interface {
Sum() int
modify(int, int)
}
type Test1 struct {
aaa int
bbb int
}
func (t *Test1) modify(a, b int) {
t.aaa = a
t.bbb = b
}
func (t *Test1) Sum() int {
return t.aaa + t.bbb
}
func (t Test1) Mul() int {
return t.aaa * t.bbb
}
func Test1Sum(t *Test1) int {
return t.aaa + t.bbb
}
func (t *Test1) modifyByAddr(a int) {
t.aaa = a
}
func (t Test1) modifyByValue(a int) {
t.aaa = a
}
func (t Test1) String() string {
res := fmt.Sprintf("aaa:%d, bbb:%d", t.aaa, t.bbb)
return res
}
func main() {
ttt := new(Test1)
ttt.aaa = 5
ttt.bbb = 2
var test1Face TestInterface
test1Face = ttt
test1Face.modify(123, 456)
fmt.Println("Sum:", ttt.Sum())
fmt.Println("Mul:", ttt.Mul())
fmt.Println("Test1Sum:", Test1Sum(ttt))
fmt.Println("old value:", ttt)
ttt.modifyByValue(222)
fmt.Println("modifyByValue:", ttt)
ttt.modifyByAddr(111)
fmt.Println("modifyByAddr:", ttt)
}