1. 程式人生 > >一起來學GO語言--GO語言函式和方法

一起來學GO語言--GO語言函式和方法

這篇部落格一起學習一下函式和方法,一般來說這兩個是一樣的,但是在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)
}

執行結果: