一、函数function
1、基本概念
函数是基本的代码块,用于执行一个任务。Go 语言最少有个 main() 函数
。函数声明告诉了编译器函数的名称,返回类型,和参数
。
Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回数组中包含的函数个数。
2、函数定义
函数定义格式如下:
func function_name( [parameter list] ) [return_types] { 函数体 }
函数定义解析:
-
func
:函数由 func 开始声明 -
function_name
:函数名称,函数名和参数列表一起构成了函数签名。 -
parameter list
:参数列表,参数就像一个占位符
,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数
。参数是可选
的,也就是说函数也可以不包含参数。 -
return_types
:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。 -
函数体
:函数定义的代码集合。
示例:
/* 函数返回两个数的最大值 */ func max(num1,num2 int) int { /* 声明局部变量 */ var result int if (num1 > num2) { result = num1 } else { result = num2 } return result }
3、函数特性
- Go 函数
不支持
嵌套、重载和默认参数 - Go 函数
支持
无需声明原型、不定长度变参、多返回值、命名返回值参数、匿名函数、闭包 - 定义函数使用关键字
func
,且左大括号不能另起一行 函数也可以作为一种类型使用
ackage main import "fmt" func main() { A(1,2,3,4,5) } // ... 不定长变参 func A(a ...int) { fmt.Println(a) }
输出:
➜ myfirstgo go run func.go [1 2 3 4 5]
不定长变参特性:
1、不可以在不定长变参后边添加其他参数 func b(a ...int,b string)
, 这种写法是错误
的
2、不定长参数可以放在其他参数后边 func b(b string,a ...int)
4、匿名函数
func main() { // 将一个函数赋值一个变量,该变量是函数类型 a := func(){ fmt.Println("匿名函数") } // 调用 a() }
5、闭包
/** * 闭包函数 * * 该闭包函数接收一个int型参数,其返回值是函数类型 * */ func closure(x int) func(int) int { fmt.Println("%p\n",&x) return func (y int) int { fmt.Println("%p\n",&x) fmt.Println(x) fmt.Println(y) return x + y } } func main() { f := closure(10); fmt.Println(f(1)) fmt.Println(f(2)) }
打印结果:
➜ myfirstgo go run func.go %p 0xc42000e228 %p 0xc42000e228 10 1 11 %p 0xc42000e228 10 2 12 ➜ myfirstgo
6、defer
- defer 的执行方式类似其他语言中的
析构函数
,在函数体执行结束后按照调用顺序的相反顺序
逐个执行 - 即使函数发生
严重错误
也会执行 - 支持匿名函数的调用
- 常用于
资源清理、文件关闭、解锁以及记录时间
等操作 - 通过与匿名函数配合可在return之后
修改
函数计算结果 - 如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则则是引用某个变量的地址
- Go没有异常机制,但有
panic/recover
模式来处理错误 -
Panic
可以在任何地方引发,但recover
只有在 defer 调用的函数中有效
简单的测试:
func main() { fmt.Println("a") defer fmt.Println("b") defer fmt.Println("c") }
上边的执行会打印什么结果呢? 会打印:a b c 吗?
让我们实际执行一下:
myfirstgo go run func.go a c b
实际打印的结果为:a c b
使用闭包
func main() { for i := 0; i < 3; i++ { // defer 普通调用 // defer fmt.Println(i) // 打印 2 1 0 // 使用闭包,引用局部变量 defer func () { fmt.Println(i) }() } }
打印结果:
➜ myfirstgo go run func.go 3 3 3
panic 使用示例:
func main() { A() B() C() } func A() { fmt.Println("FUNC A") } func B() { // 匿名函数,如果没有参数,则末尾需要使用括号 defer func() { if err := recover(); err != nil { fmt.Println("Recover is B") } }() panic("B panic") } func C() { fmt.Println("FUNC C") }
打印结果:
➜ myfirstgo go run func.go FUNC A Recover is B FUNC C ➜ myfirstgo
二、结构Struct
1.基本概念
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型
。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合
。
结构体表示一项记录,比如保存图书馆的书籍记录,每本书有以下属性:
Title :标题
Author : 作者
Subject:学科
ID:书籍ID
2.结构体定义
结构体定义需要使用 type
和 struct
语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
type struct_variable_type struct { member definition; member definition; ... member definition; }
一旦定义了结构体类型,它就能用于变量的声明,语法格式如下:
variable_name := structure_variable_type {value1,value2...valuen}
type 是定义名称,struct 是结构体类型,如同 int
类型一样。
结构体可以包含多种数据类型,数组只能是单一类型的数据集合。
访问结构体成员
如果要访问结构体成员,需要使用点号 (.) 操作符,格式为:"结构体.成员名"
。
结构体类型变量使用struct
关键字定义,实例如下:
package main import "fmt" type Books struct { title string author string subject string book_id int } func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ var Book2 Books /* 声明 Book2 为 Books 类型 */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* book 2 描述 */ Book2.title = "Python 教程" Book2.author = "www.runoob.com" Book2.subject = "Python 语言教程" Book2.book_id = 6495700 /* 打印 Book1 信息 */ fmt.Printf( "Book 1 title : %s\n",Book1.title) fmt.Printf( "Book 1 author : %s\n",Book1.author) fmt.Printf( "Book 1 subject : %s\n",Book1.subject) fmt.Printf( "Book 1 book_id : %d\n",Book1.book_id) /* 打印 Book2 信息 */ fmt.Printf( "Book 2 title : %s\n",Book2.title) fmt.Printf( "Book 2 author : %s\n",Book2.author) fmt.Printf( "Book 2 subject : %s\n",Book2.subject) fmt.Printf( "Book 2 book_id : %d\n",Book2.book_id) }
以上实例执行运行结果为:
Book 1 title : Go 语言 Book 1 author : www.runoob.com Book 1 subject : Go 语言教程 Book 1 book_id : 6495407 Book 2 title : Python 教程 Book 2 author : www.runoob.com Book 2 subject : Python 语言教程 Book 2 book_id : 6495700