go[2]-数据结构

本地缓存库分析(一):golang-lru 如果用go自带的map实现本地缓存,大概有两种实现方式: 1. sync.Map 2. map + mutex.RWLock 但有以下缺点: 1. 锁竞争严重 2. 大量缓存写入,导致gc标记阶段占用cpu多 3. 内存占用不可控 4. 不支持缓存按时效性淘汰 5. 不支持缓存过期 6. 缓存数据可以被污染:如果缓存的V是指针,那么业务修改了V的某个值为当前请求用户自己的值,在缓存中的V就被污染了 阅读详情


参考golang手册,记录数据类型相关资料;方便日后来回顾基础知识。

1. 基本数据

1.1. 布尔

布尔类型,表示真与假。true|false

1.2. 整型/浮点数

数值类型,分为整形和浮点类型,下面列举的是类型,以及读数的区间。

uint8       the set of all unsigned  8-bit integers (0 to 255)
uint16      the set of all unsigned 16-bit integers (0 to 65535)
uint32      the set of all unsigned 32-bit integers (0 to 4294967295)
uint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)

int8        the set of all signed  8-bit integers (-128 to 127)
int16       the set of all signed 16-bit integers (-32768 to 32767)
int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

float32     the set of all IEEE-754 32-bit floating-point numbers
float64     the set of all IEEE-754 64-bit floating-point numbers

complex64   the set of all complex numbers with float32 real and imaginary parts
complex128  the set of all complex numbers with float64 real and imaginary parts

byte        alias for uint8
rune        alias for int32 

整数类型按照字节数来分类,有8位、16位、32位、64位。每个数字的区间范围、内存空间都不一样。

int,uint会按照cpu字节大小最终是32位或者64位。Unicode.rune和int32等价,byte和uint8等价。

unsafe包里面提供的uintptr,不会规定内存的size,但是能容纳从c语言传递过来的内存指针。

1.2.1 整数

最高位使用了反码方式来表示。拿8位来举例子。他的取值范围是(-128 to 127)

-128= 二进制 1111 1111

127= 二进制 0111 1111

对有符号数字做位操作时,向右移将会自动补上符号位,向左移符号位不会受到影响。

    var a int8
    a = -1
    fmt.Printf("%08b\n", a)
    a = a >> 2
    fmt.Printf("%08b\n", a)
    a = a << 3
    fmt.Printf("%08b\n", a)
-0000001
-0000001
-0001000
``

这个特性需要注意,一般在操作位的时候,我们都偏向使用无符号的数字来处理。

在处理循环的时候,最好推荐使用有符号的变量来处理。防止程序出现问题。

### 无符号

将会把全部的bit位当成数值来计算。在做位操作时,可以当成数组来理解。

整数类型的运算优先级(行里面是级别相等,从上往下的列,级别是依次降低):

```go
* / % << >> & &^
+ - | ^
== != < <= > >=
&&
||

1.2.2 浮点类型

提供了 float32 float64 两种。IEEE 754标准。

所有极限值被定义在math包中。

math.MaxFloat32
math.MinInt8

float32 大约能理解成6个十进制的精度;float64能到15个十进制精度。

1.3. String

string存储了一系列的bytes,string的字节数是就是字符串的长度,而且不可能为负数。当创建了字符串之后,将不会发生改变。可以使用内建函数len取得字符串的长度。可以通过下标方式取得字符串的数值。

可以通过操作,可以直接分离出内容

str := "0123456"
fmt.Println(str[0:3]) // 012
fmt.Println(str[3:])  // 3456
fmt.Println(str[:3])  // 012

不允许对字符串中间的内容做任何修改。

.\main.go:24:9: cannot assign to str[2]

转移方式:

\x11ff 十六进制
\o1188 八进制

原生字符串,一般用于制作正则表达式。使用反引号。

const GoUsage=`Go is a tool for managing xxx
xxx... `

unicode字符集,参考主页:http://unicode.org
golang使用的是utf32或者UCS-4,每个码点占用32bit。
utf-8
ascii部分是使用1个byte,常用字使用2或3个字符来表示。
解析的时候,读取高位来判断是采取几个字节(二进制)来加载。
高位为0,就是ascii,使用1个byte
0xxxxxxx
高位为110,需要使用2个byte
110xxxxx 10xxxxxx
高位为1110,需要使用3个byte
1110xxxx 10xxxxxx 10xxxxxx
高位为11110,需要使用4个byte
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
这样能完全兼容ascii码,而且能支持字符的压缩。
unicode/utf8包中,RuneCountInString能量出来utf8字符长度。

string相关的包 bytes,strings,strconv,unicode

strings包,主要提供查找、替换、比较、阶段、拆分和合并功能;
bytes包,用于处理[]byte的库,类似于strings。由于string是不能修改的,所以一般加工字符串的时候,都通过转换成[]byte来做处理。

string和[]byte的转换。

bytes := []byte("I am byte array !")
str := string(bytes)

strconv包,用于将布尔,整型,浮点与string之间做转换;
unicode包,用于处理utf8相关操作。

1.4. const

测试实例

package learngotest

import (
	"fmt"
	"testing"
)

type Priority int

const (
	LOG_EMERG Priority = iota
	LOG_ALERT
)

func TestLogiota(t *testing.T) {
	fmt.Println(LOG_EMERG)
	fmt.Println(LOG_ALERT)
}

const (
	mutexLocked = 1 << iota // mutex is locked
	mutexWoken
	mutexStarving
	mutexWaiterShift      = iota
	starvationThresholdNs = 1e6
)

func TestLockiota(t *testing.T) {
	fmt.Println(mutexLocked)
	fmt.Println(mutexWoken)
	fmt.Println(mutexStarving)
	fmt.Println(mutexWaiterShift) // 3
	fmt.Println(starvationThresholdNs)
}

const (
	bit0, mask0 = 1 << iota, 1<<iota - 1
	bit1, mask1
	_, _
	bit3, mask3
)

func TestBitiota(t *testing.T) {
	fmt.Println(bit0, mask0) // 1,0
	fmt.Println(bit1, mask1) // 2,1
	fmt.Println(bit3, mask3) // 8,7
}

2. 复合数据类型

2.1. 数组

数组一般都是指定长度的某种类型 。由于长度无法变化,其实很少使用到。

var a[3] int
var b [3]int = [3]int{1, 2, 3} // 初始化
c := [...]int{1, 2, 3}//简略方式
r := [...]int {99:-1} // 初始化了100个元素,100号位置写-1,其他全部都写0

数组能直接做==的检测判断。
在调用函数的时候,将会赋值给函数的内部变量,如果参数使用了数组,将会存在内存拷贝。如果传递大的数组,将会有性能消耗。而且在修改数组内容时,也是在复制的数组中修改。如果想减少消耗,并且支持同步修改,还是需要使用数组指针方式来传递。

2.2. slice

切片是可变长的数组。每个元素都是相同类型。它包含了指针、长度和容量。指针是指向自己持有的slice的第一个元素,不一定是真实的数组中的第一个。长度,就是当前slice的长度。容积是全部长度。slice可以通过切片方法,分离出子串。其实本质上,他们还是指向同一个数组的。只是由于他们的指针位置不同,而体现出来不一样。
切片的方法 a[n:m]将会取出[n,m)之间的元素出来,产生新的slice。如果n没有填写,默认意思是0,m没有填写,默认就是切片的长度。所以a[:]获取全部内容。
使用make来创建一个slice:
make([]T,len,[cap])
append函数为slice追加内容。如果cap足够,那就直接添加到尾部,否则将重新创数组,将老数组copy进去,将新的内容添加到数组尾部。append都是返回一个新的数组出来,而不会去直接修改老数组。
slice类似这样的数据结构:

type IntSlice struct {
    ptr *int
    len,cap int 
}

在使用slice的时候,需要注意底层存在一个数组。如果能复用,将会大大的提高运行效率。
删除最后一元素
stack = stack[:len(stack)-1]
获取栈顶元素
top := stack[len(stack)-1]
删除其中一个元素

func remove(slice []int, i int) []int {
    copy(slice[i:],slice[i+1:])
    return slice[:len(slice)-1]
}

需要做一次内存拷贝。如果不在乎顺序,可以直接将最后位置的元素,直接赋值掉指定位置的元素,删除slice最后的元素。
在stackoverflow里面的建议是直接使用连接两个拆分的slice,这样反而会比较高效。
原文地址

func remove(slice []int, s int) []int {
    return append(slice[:s], slice[s+1:]...)
}

2.3. map

key/value方式无序的集合。golang中的map其实就是哈希表。其中key的类型需要支持==比较运算符。浮点型最好不好当成key。
创建map的方法

ages :=make(map[string]int)
ages := map[string]int {
    "alice" : 31,
    "Charlie" : 34,
}

map的元素可以通过key下标来访问
ages[“alice”]=32
fmt.Println(ages[“alice”])
通过delete对map中的元素删除
delete(ages,“alice”)
也能直接对不存在的元素直接做操作
ages[“bob”] = ages[“bob”]+1
系统会自动初始化key为bob的元素并且返回0
map中的元素不是变量,所以无法取得地址。原因也是由于随着元素的删减,可能内存空间有放大,或者缩小。所以取得的内存地址可能失效。
循环方式是

for name,age := range ages {
    fmt.Printf("%s\t%d\n",name,age)
}

由于是hash所以遍历的顺序是不固定的。map变量定义出来之后都是nil值。可以通过make语句来创建初始化。
如需要检查一个元素是否有初始化,可以通过

age, ok := ages["bob"]
if !ok {
  // 不存在元素。
}

map容器不能直接做比较操作。
go语言没有提供set类型,可以使用map来代替。

2.4. 结构体

结构体里面可以定义0-n个成员。

type T struct {
    a,b int
}
val := &T{a:1,b:2}

如果函数需要修改结构体内容,出于对效率的考虑,一般都是使用结构体的引用作为参数来传递。
结构体的嵌套

type Point struct {
    X,Y int
}
type Circle struct {
    Center Point
    Radius int
}
type Wheel struct {
    Circle Circle
    Spokes int    // 辐条
}
var w Wheel
w.Circle.Center.X = 8

go语言中能再struct中定义匿名的成员,这样就直接将其他的struct直接嵌入到了自己的结构体

type Circle struct {
    Point
    Radius int
}
type Wheel struct {
    Circle
    Spokes int
}
var w Wheel
w.X = 9

struct可以通过

fmt.Printf("%#v\n",w)

输出信息。

【git】git: ‘interpret-trailers’ is not a git command. See ‘git --help’ cents 7.6系统. yum源安装git最新版本是1.8.3 报错: git: 'interpret-trailers' is not a git command. See 'git --help'. cannot insert change-id line in .git/COMMIT_EDITMSG 解决: git add xxx git commit -m "xxx" 然后修改 vim .git/hooks/commit-msg #if test -n "${reviewurl}" ; th 阅读详情

相关推荐

使用Kolla部署多节点Rocky版本OpenStack

openstack命令行客户端使用,post-deploy会在 /etc/kolla/目录下生成文件admin-openrc.sh。每次使用openstack命令时执行source /etc/kolla/admin-openrc.sh(manager节点执行)source /etc/kolla/admin-openrc.sh (将文件内容复制到/etc/profile中,即可一直生效)3.2.2 开始安装kolla-ansible,要带上--ignore-installed PyYAML,否则可能会报错。

gyc1206的博客 1927

Go-2.1:Go语言的基础学习

数组切片 package main import "fmt" func main() { intArray := []int{0,1,2,3,4,5} fmt.Println(intArray) //切片 fmt.Println(intArray[:]) //取前2位 fmt.Println(intArray[:2]) //取2位后数据 0 1 2 fmt.Println(intArray[2:]) //取2-3位数据,包前不包后 fmt.Println(intArray[2:3

u013205724的博客 230

231003-四步MacOS-iPadOS设置无线竖屏随航SideCar

新建虚拟屏幕参考文献。

专注机器学习之路 7487

golang iota_iota在golang中创建有效常数

golang iotaSome concepts have names, and sometimes we care about those names, even (or especially) in our code. 有些概念有名称,有时我们会在代码中甚至(或尤其是)关心这些名称。 At other times, we only care to distinguish one thing ...

weixin_26741341的博客 162

Valeo近场数据集:多模态行人意图检测技术解析

行人意图检测是智能驾驶系统的关键技术,通过分析行人运动轨迹预测其行为意图。传统方法受限于单传感器数据,难以应对复杂场景。多模态融合技术结合视觉、LiDAR和惯性测量数据,显著提升检测精度。Valeo近场数据集(VNF)创新性地采用鱼眼相机、多LiDAR和动作捕捉系统,实现3D姿态与意图标签的精准对齐。该数据集支持开发距离自适应的行人感知算法,在ADAS防碰撞、智能迎宾等场景具有重要应用价值。关键技术包括传感器同步、3D姿态重建和时空图卷积网络,为行业提供了标准化评估基准。

weixin_30566111的博客 660

Arduino IDE 2.3.2 配置 UNO R4 WIFI 开发环境避坑指南(附LED矩阵驱动测试)

本文详细介绍了如何在Arduino IDE 2.3.2中配置UNO R4 WIFI开发环境,并提供了LED矩阵驱动的实战指南。从开发环境搭建到硬件连接,再到LED矩阵的初始化和弹球动画实现,手把手教你避开常见配置陷阱,最终实现流畅的动画效果。特别适合刚接触UNO R4 WIFI的开发者快速上手。

weixin_28675839的博客 220

golang数据结构初探之iota

iota Go语言的iota常用于const表达式中,其值是从0开始的,const声明块中每增加一行,iota值都会自增1。 使用iota可以简化常量的定义,但其规则必须牢记,否则在阅读源码时可能会造成误解或者障碍。本章我们尝试从编译器的角度来理解iota,从而加深认识。 特性速览 在常量声明语句中,iota经常用于声明连续的整型常量。iota的取值与其出现的位置强相关。 iota在const关键字出现时被重置为0 const声明块中每新增一行,iota的值自增1 这种描述本身没有错误,在简单的语句中套

Steven的专栏 7580

C#上位机+YOLOv8实战:摄像头/视频流实时目标检测(工业级优化+完整可运行源码)

纯C#实现,无Python依赖,适配工业工控机部署;工业级优化:解决帧率、内存、鲁棒性三大核心问题;代码完整可复用,支持摄像头/视频流/RTSP多源检测;避坑指南覆盖开发中90%的常见问题,降低落地成本。相较于传统方案,该方案兼顾实时性与易用性,成本仅为商用视觉库的1/10,可快速落地到工业质检、安防、物流等场景。后续可拓展方向包括:自定义数据集训练、GPU加速推理、工业通信(PLC/串口)对接等。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 733

GitHub_Trending/go2/Go:数据结构实现指南

在计算机科学领域,数据结构是构建高效算法的基石。GitHub_Trending/go2/Go项目提供了一个全面的Go语言数据结构实现库,涵盖了从基础到高级的各种数据结构。本文将通过深入分析该项目的核心实现,为您提供一份专业的数据结构学习指南。 ## 核心数据结构实现 ### 1. 链表(Linked List) 链表是最基础的数据结构之一,该项目提供了单链表、双向链表和循环链表的完整实现。 ...

gitblog_00223的博客 884

STM实战开发(13):STM32开发:使用光敏电阻检测光照强度

光敏电阻(LDR)是一种电阻值受光照强度影响的半导体材料。当光照强度增大时,光敏电阻的电阻值降低;而当光照强度减小时,电阻值则增大。光敏电阻的电阻变化与入射光的强度之间并不是线性关系,而是呈对数型的变化。LDR通常由硫化镉(CdS)或其他半导体材料构成,材料对不同波长的光有不同的响应特性。一般而言,光照强度越强,光敏电阻的电阻值越低,反之则越高。本文介绍了如何使用STM32与光敏电阻(LDR)结合,进行光照强度检测的实现方法。通过配置STM32的ADC模块,读取光敏电阻的电压信号,并根据电压计算光照强度。

2201_76125393的博客 3018

【学习系列】SAP RAP 20:Unmanaged场景开发示例-调用BAPI、BAPI包装类、BO接口创建标准采购订单

本文介绍了在SAP RAP(Restful ABAP Programming)框架下,通过三种方式实现采购订单创建的方案。首先分析了RAP框架对传统BAPI调用的限制,特别是禁止显式COMMIT语句的要求。随后详细阐述了三种实现方式:1)直接调用传统BAPI(仅支持OP环境);2)使用BAPI包装类(仅支持OP环境);3)调用标准业务对象接口(支持所有环境)。 文章重点说明了在unmanaged场景下的技术实现细节,包括字段控制、缓冲区管理、测试运行与实际调用的分离处理等。针对每种方式都提供了完整的实施步骤

DeveloperMrMeng的博客 598

GO语言Part2——数据结构01

GO语言之数据结构01

kart jim的优快云博客 188

cesium 实现经纬线绘制和经纬度标注

废话不对数直接上线效果图及代码 1.效果图 2.实现代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=

一碗老面的博客 2569

Go最新Redis—数据结构(2),2024年最新Golang面试题库

总之,Redis 的 Quicklist 是一种高效的列表实现,它综合了压缩列表和双向链表的优点,通过多个压缩列表节点和双向链表结构实现了内存紧凑且访问高效的列表操作。在处理各种规模的列表数据时,Quicklist 都能提供较好的性能和可扩展性。

2401_84911322的博客 868

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

GitHub_Trending/go2/Go:树数据结构实现深度解析

还在为选择合适的树结构而烦恼?面对海量数据时,二叉搜索树性能急剧下降?本文将为你全面解析GitHub_Trending/go2/Go项目中四种核心树数据结构的实现,助你掌握高效数据存储与检索的终极武器! 通过本文,你将获得: - ???? 四种树结构的完整实现原理 - ⚡ 各树结构的性能对比与适用场景 - ????️ 详细的API使用示例 - ???? 可视化操作流程解析 - ???? 实际应用场景推荐 ##...

gitblog_00867的博客 903

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

go-swagger 模型生成完全指南:从 Swagger 2.0 Schema 到 Go 原生数据结构

[go-swagger](https://link.gitcode.com/i/88c9db32d8652bcf170e5bb789a36653) 是 Go 语言生态中实现 Swagger 2.0 规范的工具链,其核心能力之一是根据 Swagger 规范中的 schema 定义自动生成可直接用于序列化与校验的 Go 原生数据结构。本文以仓库官方文档 [docs/reference/models/_

gitblog_00669的博客 915

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

GitHub_Trending/go2/Go:栈数据结构算法深度解析

在日常开发中,你是否遇到过这样的场景:需要实现撤销操作、表达式求值、函数调用管理,或是浏览器前进后退功能?这些看似不同的需求背后,都隐藏着一个共同的核心数据结构——栈(Stack)。作为LIFO(Last In First Out,后进先出)数据结构的经典代表,栈在算法设计和系统开发中扮演着至关重要的角色。 本文将深入解析GitHub Trending项目go2/Go中的栈实现,带你全面掌握栈的...

gitblog_00977的博客 664

Go最全数据结构与算法 — 树的常见操作(Golang)_golang 树结构(2),Golang多线程实现方式及并发与同步

树的最大层级数,被称为书的高度或深度。

2401_84910817的博客 356

golang数据结构研究[2]切片篇

数据结构是切片,即动态数组,其长度并不固定,我们可以向切片中追加元素,它会在容量不足时自动扩容。可以认为是封装了扩容操作的数组。为什么需要有了切片又需要数组?数组与切片在golang设计层面有什么区别呢?切片因为在设计时就考虑长度是不确定的,所以在编译期间生成伪代码时,就只确认了切片元素的类型。与上一节的数组在编译期间就确定了长度与边界的数组不同。t!

zasx1994的专栏 810

Go版数据结构 -【2.2 链表】

链表是一种常见的线性数据结构,与数组不同的是,链表中的元素并不存储在连续的内存空间中,而是通过指针连接在一起。 链表非常适合需要频繁插入、删除操作的场景,因为它不需要像数组那样频繁移动数据。

Swxctx 1552

2024年Go最新数据结构与算法 — 数组常见操作(Golang)_go语言数组运算(2),38岁的中年失业者怎么活下去

错误的意思是不能使用newArray给Array赋值,为什么Java语言中可以,而Golang语言中就不行了呢?本文将着重讲数一下Java语言和Golang语言对于数组的基本操作实现的差异性,同时可加深对语言的理解。解决办法是使用切片,Golang语言的切片来实现数组的功能,使用 make() 函数构造切片。,这个特性会导致在使用不同编程语言实现数组的基本操作时,会有很大的差异性;:数组只能保存相同数据类型元素,元素的数据类型可以是任何相同的数据类型。:数组中的元素是有序的,通过下标访问。

2401_84925152的博客 483

Go版数据结构 -【2.1 数组】

数组是我们常用的一种数据结构,在大部分编程语言中都原生支持,数组在我们的日常开发工作中也是一种必不可少的数据结构。

Swxctx 1058

GoLang之channel底层的数据结构是什么、channel的创建(2)

GoLang之channel底层的数据结构是什么、channel的创建(2)

weixin_52690231的博客 460

我的Go+语言初体验——GO+实现数据结构之【栈与其应用】(2)

【我的Go+语言初体验” | 征文活动进行中…】 以写促学,接下来,我将带大家使用 GO+ 逐步 实现常见的数据结构 欢迎关注【我的Go+语言初体验——实现数据结构】系列,持续更新中… 往期文章 我的Go+语言初体验——实现数据结构之【数组 切片 Map】(1) 文章目录 ...

Create value with coding 1万+

2Golang基本数据结构——变量与常量

变量与常量 1. 编写测试程序 2. 实现 Fibonacci 数列 3. 变量赋值 4. 常量定义

weixin_62173811的博客 307

Go版数据结构 -【3.2 队列】

队列与栈有相同的地方,但是也略有不同。本节我们将讲解队列的基本概念及Go语言实现。

Swxctx 882
上一篇: FSM-Golang
下一篇: 3d数学
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值