一起來學GO語言--GO語言函式和方法
阿新 • • 發佈:2018-12-21
這篇部落格一起學習一下函式和方法,一般來說這兩個是一樣的,但是在GO語言裡面,我理解是函式就是能被呼叫的方法,沒有固定的繫結在那個型別上面,而方法是繫結在某個特定型別上的函式。這是我的理解,如有錯誤,請大家指正。下面我們先從函式起。
1、函式的多值返回
我們知道從map中取值得時候,返回的是兩個結果,我們使用range遍歷的時候,返回的也是兩個結果,在GO語言裡面支援函式的多值返回,下面我們自己寫一段程式碼來說明:
// stydy project main.go package main import ( "fmt" ) //定義一個學生的結構體 type Student struct { ID int //學號 name string //姓名 score int //成績 } //判斷學生成績級別,返回兩個引數,級別和錯誤 func JudgeScoreLevel(s Student) (string, error) { if s.score < 0 { return "unknown", fmt.Errorf("student error") } var level string var err error switch { case s.score >= 90: level, err = "A", nil case s.score >= 70 && s.score < 90: level, err = "B", nil case s.score >= 60 && s.score < 70: level, err = "C", nil case s.score < 60: level, err = "D", nil } return level, err } func main() { student := Student{123456, "張三", -50} level, err := JudgeScoreLevel(student) fmt.Println(level, err) }
上面 程式碼我們定義了一個學生的結構體,函式中當成績小於0時,我們返回錯誤值,當正常時,err賦值nil
2、匿名函式
匿名函式就是在關鍵字func後面沒有函式名稱的函式為匿名函式,匿名函式可以作為函式的返回值,匿名函式只能在表示式的內部進行定義,下面用程式碼來說明幾種情況。
// stydy project main.go package main import ( "fmt" ) //定義一個學生的結構體 type Student struct { ID int //學號 name string //姓名 score int //成績 } //將函式當作返回值 func getName(s Student) func() int { if s.name == "張三" { return func() int { return s.score } } else { return func() int { return -1 } } } func main() { func() { fmt.Println("匿名無參無返回值") }() func(i int) { fmt.Printf("有參無返回值i=%d\n", i) }(2) a := func(i int) int { fmt.Printf("有參有返回值i=%d\n", i) return i } a(3) s := Student{123456, "張三", 99} f := getName(s) fmt.Println(f()) }
上面的程式碼中列舉出了匿名函式的幾種方式,請大家參考。
3、函式的延遲呼叫
當我們測試一個函式的效能的時候,需要知道函式開始執行時間和執行結束時間,執行結束指當return結束後,這個時候,我們就需要用到函式的延遲呼叫,延遲呼叫的關鍵字defer,這個有些像java中的finally中執行的程式碼。下面我們用程式碼來進行說明。
// stydy project main.go package main import ( "fmt" "time" ) func DoSomething(dosomething string) { defer LogPrint()() time.Sleep(10 * time.Second) fmt.Printf("do something:%s\n", dosomething) } func LogPrint() func() { startTime := time.Now() fmt.Printf("start execute time:%d\n", startTime.Second()) return func() { endTime := time.Now() fmt.Printf("execute end time:%d\n", endTime.Second()) } } func main() { s := "clean washroom" DoSomething(s) }
執行結果:
大家可以把defer去掉看一下結果
4、方法
方法和函式很相似,區別在於定義時在函式名稱的前面多了一個引數,這個引數把這個方法繫結在這個引數對應的型別上。下面我們用一個例項來說明,有一個方法,我們需要比較兩個學生的成績,返回成績高的學生,下面來看一下程式碼:
// stydy project main.go
package main
import (
"fmt"
)
type Student struct {
ID int
Name string
Score int
}
func compareScore(s1, s2 Student) Student {
if s1.Score > s2.Score {
return s1
} else {
return s2
}
}
func (s1 Student) compareScore(s2 Student) Student {
if s1.Score > s2.Score {
return s1
} else {
return s2
}
}
func main() {
s1 := Student{123456, "張三", 95}
s2 := Student{234567, "李四", 99}
s := compareScore(s1, s2)
fmt.Println(s)
s = s1.compareScore(s2)
fmt.Println(s)
}
執行結果:
從結果看出,結果都一樣
5、結構內嵌
假如現在有一個結構體Class班級,班級裡面有學生,那麼Class是可以直接呼叫Student的方法的,下面用程式碼說明:
// stydy project main.go
package main
import (
"fmt"
)
type Student struct {
ID int
Name string
Score int
}
type Class struct {
Student
ClsName string
}
func (s Student) GetStudentScore() int {
return s.Score
}
func main() {
c := Class{Student{123466, "張三", 95}, "一班"}
score := c.GetStudentScore()
fmt.Println(score)
}
執行結果: