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

相关推荐
ly7689几秒前
Spring Boot 3.2 虚拟线程在 Web 层与 JDBC 池的实践边界
前端·spring boot·后端·tomcat·jdbc·虚拟线程
盖伦发发12 分钟前
SpringCloud Alibaba Sentinel 教学:限流、熔断、降级、线程/信号量隔离、活动过载保护
后端·软件工程
考虑考虑8 小时前
数据库中的EXISTS
运维·数据库·后端
郑州光合科技余经理9 小时前
国际版外卖系统:税率字段怎么和订单主流程解耦
android·java·开发语言·前端·后端·php·ai编程
毅炼9 小时前
Rover-Suite 开源发布:轻量服务注册中心与网关一体化方案
java·后端·系统架构·gateway
苏三说技术14 小时前
为什么越来越多人用OpenWiki?
后端
IT_陈寒14 小时前
Java里用Stream.parallel()翻车实录,这性能还不如单线程
前端·人工智能·后端
Bs_MoneyMagnet14 小时前
基于springboot+vue的生态果园采摘预约系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·毕业设计·计算机毕业设计
码事漫谈14 小时前
FDE 的起源、形态与真实边界
后端
ServBay15 小时前
Grok Bot 还是 OpenClaw?聊聊真正能替人打杂的 AI 智能体
后端·aigc·grok