1.channel:
channel一般被理解为消息队列或者为线程同步而创建的数据结构.
1.1channel的创建:
go
package main
import "fmt"
func main() {
//channel的创建.
channel := make(chan int)
//创建一个缓冲区为100的channel
channel100 := make(chan int, 100)
}
chan是channel的缩写,也是创建channel的关键字.int是这个channel存储元素的数据类型.当后面还有参数的话,代表缓冲区的大小.
1.2channel的读写:
go
package main
import "fmt"
func main() {
var count = 5
channe := make(chan int, count)
for i := range count {
channe <- i
}
for i := 0; i < count; i++ {
fmt.Println(<-channe)
}
}
执行结果:

需要注意的是缓冲区满了无法写入,会导致程序阻塞.缓冲区为空时,也会阻塞.
1.3channel与消息队列:
channel消息被消费后会被移除,消息队列被消费后可以被存储起来进行回溯.
消息队列中的消息可以被多个消费者消费.channel不可以.
channel是进程级缓存,可以用于多个协程之间的通信.消息队列可以用于多个进程通信.
channel只是通道,可以无缓冲区.不重视消息的存储.消息队列需要考虑存储用来保证消息的可靠性.
2.自定义结构体:
go
type typeName struct {
filedName1 string
filedName2 int
filedName3 bool
}
type关键字代表这是一个自定义数据类型.
typeName是这个类型的名称.
struct指定该类型是一个结构体.
filedName是字段名称,后面是字段类型.
2.1自定义结构体运用:
go
package main
import "fmt"
func main() {
var per = person{
name: "itbo",
age: 25,
email: "itbo.com",
}
fmt.Println("person: ", per)
}
type person struct {
name string
age int
email string
}
执行结果:

2.2初始化后赋值:
ini
var per1 = person{}
per1.name = "itbo"
per.age = 20
per1.email = "itbo.com"
2.3new创建实例:
go
package main
import "fmt"
func main() {
var per1 = person{}
per1.name = "itbo"
per1.age = 20
per1.email = "itbo.com"
fmt.Printf("per1 %T", per1)
// new创建实例.
var newPer = new(person)
fmt.Printf("newper %T", newPer)
}
type person struct {
name string
age int
email string
}
执行结果:

从输出结果可以看出,通过new创建的是指针类型.
2.4自定义结构体访问权限:
未提供专门的关键字进行控制.而是通过类型或者字段名称首字母大小写来进行控制.首字母大写可以全局运用.小写就是同一个包下.(同一包,暂时理解为同一目录下).
3.自定义结构体实现bitMap:
3.1自定义结构体bitMap:
go
type bitmap struct {
data []uint8
}
3.2set函数设置值:
go
func set(bitmap *bitmap, index int) {
//将某个二进制位置设置为1.
i := index - (len(bitmap.data)<<3 - 1)
if i > 0 {
//调用扩容函数.
expandBitmap(bitmap, i)
}
//将index右移三位.
dataIndex := index >> 3
//设置对应的二进制为1
bitmap.data[dataIndex] = bitmap.data[dataIndex] | 1<<(index%8)
}
3.3检查函数:
perl
func checkIndex(bitmap *bitmap, index int) {
//如果要获取的pos位置已经超出了当前容量
if index-(len(bitmap.data)<<3) > 1 {
fmt.Println(index, "是否存在:", false)
return
}
//pos位置右移三位,代表除以8
dataIndex := index >> 3
flag := bitmap.data[dataIndex]&(1<<(index%8)) > 0
fmt.Println(index, "是否存在:", flag)
}
3.4扩容函数:
go
func expandBitmap(bitmap *bitmap, index int) {
expand := (index + 7) >> 3
//创建新的切片,并复制原来的数据
newData := make([]uint8, expand+len(bitmap.data))
copy(newData, bitmap.data)
bitmap.data = newData
}
3.5主函数:
go
package test
import "fmt"
func main() {
bitmap := new(bitmap)
set(bitmap, 64)
checkIndex(bitmap, 63)
checkIndex(bitmap, 64)
}
执行结果:

需要注意的是uint8,需要通过除以8来进行判断处于哪个区间中.再去判断落在这个区间的哪个位置.
语雀地址www.yuque.com/itbosunmian...?
《Go.》 密码:xbkk 欢迎大家访问.提意见.