Go语言学习笔记(三)复杂数据类型channel和自定义结构

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 欢迎大家访问.提意见.

相关推荐
小谢小哥1 小时前
63-Gradle构建详解
java·后端·架构
MacroZheng1 小时前
给Claude Code装上这个超酷的状态栏,瞬间高大上了!
java·人工智能·后端
SimonKing1 小时前
langchain4j进阶:AI记忆与RAG
后端
BingoGo1 小时前
改变 PHP 未来的 RFC Polling API
后端·php
程序员cxuan1 小时前
这个 6.6 k star 的仓库,我差点删库了。
人工智能·后端·程序员
知彼解己1 小时前
SQLite 核心实战:后端工程师视角
后端·golang·ai编程
IT_陈寒2 小时前
被Vite的HMR坑惨了,原来这样配置才能用对!
前端·人工智能·后端
凌览2 小时前
为什么我不推荐一人公司用PostgreSQL
前端·后端·node.js
我是一颗柠檬2 小时前
【Java后端技术亮点】Feed流三级缓存设计,从10秒到100毫秒的优化实战
java·开发语言·后端·缓存