Go 语言概述 (下)
函数
定义函数
main.go
package main
import (
"fmt"
)
func main() {
fmt.Println(add(1, 2))
}
func add(a int, b int) (int) {
return a + b
}
注: 前几个函数参数的类型可以省略, 最后一个不行. func add(a, b int)
函数是第一类型, 可以作为参数或返回值:
返回值
main.go
package main
import (
"fmt"
)
func main() {
f := add
fmt.Println(f(1, 2))
}
func add(a , b int) (int) {
return a + b
}
参数
package main
import (
"errors"
"fmt"
)
type operator func(a, b int) (int, error) // operator作为一类函数的类型
func main() {
fmt.Println(compute(1, 0, div)) // 0 division by zero
fmt.Println(compute(1, 2, add)) // 3 <nil>
}
// compute接受运算数和operator函数
func compute(a, b int, f operator) (int, error) {
return f(a, b)
}
// div属于operator类型
func div(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
// add属于operator类型
func add(a, b int) (int, error) {
return a + b, nil
}
defer
defer 定义延迟调用,无论函数是否出错,它都确保结束前被调用.
main.go
package main
import (
"fmt"
)
func main() {
sayHello(1, 0)
}
func sayHello(a, b int) {
defer func() {
fmt.Println("1")
}()
defer func() {
fmt.Println("2")
}()
defer func() {
fmt.Println("3")
}()
fmt.Println(a / b) // 出错
fmt.Println("hello world") // 出错后,这句代码没有执行
}
输出结果:
3
2
1
panic: runtime error: integer divide by zero
goroutine 1 [running]:
main.sayHello(0x1, 0x0)
/home/fenggese/workspace/go/src/fenggese.com/test/main.go:24 +0x19a
main.main()
/home/fenggese/workspace/go/src/fenggese.com/test/main.go:8 +0x33
exit status 2
- defer延迟调用的函数列表是按照栈的结构存储的, 后入先出的顺序。
- 无论函数是否出错,defer都确保结束前被调用。
数组
main.go
package main
import (
"fmt"
)
func main() {
a := make([]int, 0, 5)
fmt.Println("before: ", a)
for i := 0; i < 10; i ++ {
a = append(a, i)
}
fmt.Println("after: ", a)
}
运行结果:
注: 数组大小是固定的,append()函数原理是生成了一个新的数组.
字典
mian.go
package main
import (
"fmt"
)
func main() {
m := make(map[string]int)
m["a"] = 1
m["b"] = 2
x, ok := m["c"] // 使用ok-idiom获取值, 可知道key/value是否存在
fmt.Println(x, ok)
b := m["b"]
fmt.Println(b)
}
输出结果:
ok-idiom 模式,是指在多返回值中用一个名为ok的布尔值来标示操作是否成功,因为很多操作默认返回0,所以要用ok来说明0是原本应获得的值,还是默认的返回值.
注: x, ok := map["c"]
中 x 和 ok 的值类型似乎带有了 left 和 right属性. 具体为什么还不知道==
看下面代码:
main.go
package main
import (
"fmt"
)
func main() {
m := make(map[string]int)
m["a"] = 1
m["b"] = 2
x, ok := m["c"]
fmt.Println(x, ok)
x := m["b"] // x 这里会报错 ???
fmt.Println(x)
}
报错截图:
结构体
main.go
package main
import (
"fmt"
)
type user struct { // 名为 user 的结构体
name string
age int
}
type user_account struct {
user // 嵌套其他结构体
account string
password string
}
func main() {
u := user{"fenggese", 22}
a := user_account{u, "fenggese123", "123456"}
fmt.Println(u)
fmt.Println(a)
}
运行结果:
接口
未完待续…