Go语言入门笔记(三)
范围
range
关键字用于for
循环中迭代数组、切片、通道或集合(map)的元素,在数组和切片中它返回元素的索引和索引对应的值,在集合中返回key-value
对的key
值。- 示例 以上代码输入:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21func main() {
// 在数组上使用 range 将传入 index 和 value 两个变量
nums := []int{1,2,3}
sum := 0
for _, v := range nums {
sum += v
}
fmt.Println("sum:", sum)
// range 也可以用在 map 的键值对上。
kvs := map[string]string{"a":"apple", "b":"banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
// range 可以用来枚举 Unicode 字符串。第一个参数是字符的索引,第二个是字符(Unicode 的值)本身。
for i, c := range "Go" {
fmt.Println(i, c)
}
}1
2
3
4
5sum: 6
b -> banana
a -> apple
0 71
1 111
集合
集合定义格式
可以使用内建函数
make
也可以使用map
关键字来定义集合:1
2
3
4
5/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type
/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)如果不初始化
map
,那么就会创建一个nil map
。nil map
不能用来存放键值对1
2
3
4
5
6
7
8
9var countryCapitalMap map[string]string
countryCapitalMap = make(map[string]string)
countryCapitalMap["France"] = "Paris"
countryCapitalMap["China"] = "Beijing"
countryCapitalMap["Japan"] = "Tokyo"
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap[country])
}delete()
函数delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。实例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22func main() {
var countryCapitalMap map[string]string
countryCapitalMap = make(map[string]string)
countryCapitalMap["France"] = "Paris"
countryCapitalMap["China"] = "Beijing"
countryCapitalMap["Japan"] = "Tokyo"
fmt.Println("删除前:")
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap[country])
}
delete(countryCapitalMap, "Japan")
fmt.Println("\n删除了 key 为 Japan 的条目")
fmt.Println("\n删除后")
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap[country])
}
}以上输入结果为:
1
2
3
4
5
6
7
8
9
10删除前:
France 首都是 Paris
China 首都是 Beijing
Japan 首都是 Tokyo
删除了 key 为 Japan 的条目
删除后
France 首都是 Paris
China 首都是 Beijing
接口
- Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
1
2
3
4
5
6
7
8/* 定义接口 */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
} - 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26type Man interface {
showName() string
showAge() int
}
type People struct {
name string
age int
}
func (people People) showName() string {
return people.name
}
func (people People) showAge() int {
return people.age
}
func main() {
var people1 Man
people1 = People{"张三", 20}
fmt.Println(people1.showName(), people1.showAge())
}
// 张三 20
并发
通过
go
关键字来开启goroutine
即可。goroutine
是轻量级线程,goroutine
的调度是由Golang
运行时进行管理的,语法格式如下:1
go 函数名( 参数列表 )
例如:
1
go f(z, x, y)
开启一个新的
goroutine
:1
f(z, x, y)
Go
允许使用go
语句开启一个新的运行期线程, 即goroutine
,以一个不同的、新创建的goroutine
来执行一个函数。 同一个程序中的所有goroutine
共享同一个地址空间。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("Hello")
say("World")
}以上代码输出:
1
2
3
4
5
6
7Hello
Hello
World
World
Hello
Hello
World输出的 hello 和 world 是没有固定先后顺序。因为它们是两个 goroutine 在执行
通道
通道
channel
是用来传递数据的一个数据结构。1
2
3ch := make(chan int) // 声明 ch 通道
ch <- v // 把 v 发送到通道 ch
v := <- ch // 从 ch 接受数据并赋值给 v示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21func sum(s []int, c chan int) {
num := 0
for _,v := range s {
num += v
}
c <- num
}
func main() {
s := []int{1, 2, 3, 4, 5, 6}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c
fmt.Printf("x=%d,y=%d,x+y=%d", x, y, x+y)
}
// x=15,y=6,x+y=21通道缓存区
通道可以设置缓冲区,通过 make 的第二个参数指定缓冲区大小:
1
ch := make(chan int, 100)
带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。
遍历通道与关闭通道
通过 range 关键字来实现遍历读取道的数据,类似于与数组或切片。格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18func sum(n int, c chan int) {
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x+y
}
close(c)
}
func main() {
c := make(chan int, 10)
go sum(cap(c), c)
for i := range c {
fmt.Print(i, " ")
}
}
// 0 1 1 2 3 5 8 13 21 34
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mr.Wantの博客!