五、Go语言复合数据类型(下)
@Author:Runsen
复合数据类型主要包含Go中的一些复杂类型,主要有指针类型,数组类型,切片类型,结构体类型,Map类型和Channel类型
下面,我们继续学习结构体类型,Map类型和Channel类型。
结构体类型
在C语言我们都接触过结构体,结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
下面就是结构体定义:
type struct_variable_type struct { member definition; member definition; ... member definition;
}
- 1
- 2
- 3
- 4
- 5
- 6
一旦定义了结构体类型,它就能用于变量的声明,具体的声明方法如下所示。
variable_name := struct_variable_type {value1, value2...valuen}
- 1
下面,我们看一个声明结构体的具体示例。
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
// 三种声明的方法
var p1 Person
p1.Name = "Runsen"
p1.Age = 20
fmt.Println(p1)
var p2 = Person{Name:"Runsen", Age:20}
fmt.Println(p2)
p3 := Person{Name:"Runsen", Age:20}
fmt.Println(p3)
}
{Runsen 20}
{Runsen 20}
{Runsen 20}
- 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
- 26
Map类型
Go和Python一样,都有map。在Python里叫做字典,在Go里叫做映射。
Map是一种常用的kv数据结构,Go语言的Map就是哈希表数据结构。
声明map类型变量
map[keyType]valueType
- 1
其中:
- keyType:是key的类型
- valueType:是key对应的值的类型
map类型的初始值是nil,要使用需要使用make()函数来初始化分配内存地址,语法如下:
make(map[keyType]valueType, [cap])
- 1
其中cap 表示map的容量。该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。
下面尝试着在结构体类型中使用Map,具体代码如下。
package main
import ( "fmt"
)
type Student struct { name string age int
}
func useMap() { //使用前应该先初始化, 否则panic报错 // var map1 map[string]string // map1["a"] = "b" // will panic map1 := make(map[string]Student) map1["s1"] = Student{name:"Runsen", age:20} fmt.Printf("%v\n", map1) //map[s1:{Runsen 20}]
}
func main() { useMap()
}
- 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
Channel类型
go的channel,channel翻译为频道,顾名思义用来通信的,它是go一种特殊的数据类型,有点像Linux系统中的管道/消息队列。
这里go是用于goroutines之间的通信,goroutine可以说 是用户的线程,不同的 goroutine 之间是有消息传递这个需求的。
既然 channel 是一个管道,用来满足不同 goroutine 间交换消息的。那么实现这样一个管道要怎么做呢?其实很简单。下面先把示例代码贴出来。
package main
import ( "fmt" "time"
)
func main() {
ch := make(chan int) // 无缓冲 go send(ch)
go receive(ch)
time.Sleep(time.Second * 1)
}
func send(ch chan int){ ch <- 1 ch <- 2 ch <- 3 ch <- 4 ch <- 5
}
func receive(ch chan int){ var recv int for{ recv = <- ch fmt.Println(recv) }
}
- 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
- 26
- 27
- 28
- 29
- 30
- 31
- 32
输出结果:
1
2
3
4
5
- 1
- 2
- 3
- 4
- 5
首先main函数开启了两个goroutine,一个用于执行send函数,该函数每次向channel ch中发送写入一个int数值。一个执行receive函数,该函数每次从channel ch中读取一个int数值。
如果当channel中没有数据可读时,receive goroutine则会进入阻塞状态。因为receive中使用了for无限循环,表示receive这个goroutine会一直阻塞下去,直到从channel ch中读取到数据,读取到数据后进入下一轮循环由被阻塞在recv = <-ch上。
当main函数中的睡眠时间到了指定的时间后,main程序终止,意味着主程序结束,所有goroutine停止执行。
文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。
原文链接:maoli.blog.csdn.net/article/details/107835338
- 点赞
- 收藏
- 关注作者
评论(0)