这篇博客一起学习一下函数和方法,一般来说这两个是一样的,但是在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)
}
执行结果: