go学习 3、基础数据类型

3、基础数据类型

  • 基础数据类型:数字、字符串、布尔型
  • 复合类型:数组、结构体
  • 引用类型:指针、切片、字典、函数、通道
  • 接口类型

3.1 整型

有符号、无符号 int8/int16/int32/int64 uint8/uint16/uint32/units 64
Unicode字符rune类型是和int32等价的类型,通常用来表示一个Unicode码点,这两个名称可以互换使用。
byte和unit8是等价类型,byte类型一般用于强调数值是一个原始的数据而不是一个小的整数。
一种无符号的整数类型unitptr,没有指定具体的bit大小但是足以容纳指针。只有在底层编程时才需要。
int 和int32也是不同的类型,即使int的大小也是32bit。需要显式类型转换。
二元运算符:算术运算、逻辑运算、比较运算(优先级顺序)
%取模运算符的符号和被取模数的符号总是一致的。仅用于整数间的运算。 -5%3=-2
数据溢出

^ //位运算XOR,作为二元运算符时是按位异或,用作一元运算符时表示按位取反
&^ //位清空,按位清零
z=x &^ y//y=1,z=0;y=0,z=x

倾向于使用有符号的int类型
八进制前缀0,十六进制前缀0x

o:=0666
fmt.Printf("%d %[1]o %#[1]o\n",o)//438 666 0666

[1]:再次使用第一个操作数
#:输出时生成前缀
字符使用%c参数打印,用%q参数打印带单引号的字符

3.2 浮点数

float32/float64
%g 打印浮点数
对应表格的数据,使用%e(带指数)或%f形式打印可能更合适
math.IsNaN用来测试一个数是否是非数NaN
math.NaN返回非数NaN对应的值

3.3 复数

complex64/complex128 real()实部 imag()虚部
math/cmplx包提供了复数处理的很多函数

3.4 布尔型

true/false

3.5 字符串

字符串是一个不可改变的字节序列。但可以给一个字符串变量分配一个新字符串值。
不变性意味着如果两个字符串共享相同的底层数据的话也是安全的。
文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列

s:="left foot"
t:=s
s+=", right foot"
s[0]='L'//编译错误

3.5.1 字符串面值

将一系列字节序列包含包含在双引号,“hello,world”
Go语言源文件总是用UTF8编码,并且Go语言的文本字符串也以UTF8编码的方式处理,因此我们可以将Unicode码点也写到字符串面值中。
在一个双引号包含的字符串面值中,可以用以反斜杠\开头的转义序列插入任意的数据。

\a响铃
\b退格
\f换页
\n换行
\r回车
\t制表符
\v垂直制表符
单引号(只用在‘"形式的rune符号面值中)
‘’双引号(只用在“…”形式的字符串面值中)
\反斜杠
可以通过十六进制或八进制转义在字符串面值包含任意的字节。一个十六进制的转移形式\xhh,其中两个h表示十六进制数字(大写或小写都可以)。一个八进制转义形式是\ooo,包含三个八进制的o数字(0到7),但不能超过\377(对应一个字节的范围,十进制是255)。每一个单一的字节表达一个特定的值。
一个原生的字符面值形式是’…',使用反引号代替双引号。没有转义操作,全部的内容都是字面的意思,包含退格和换行。唯一的特殊处理是会删除回车以保证在所有平台上的值都是一样的。
原生字符串面值用于编写正则表达式会很方便,因为正则表达式往往会包含很多反斜杠。
const GoUsage=’Go is a tool for managing Go source code.

Usage:
	go command [arguments]
...

3.5.2 Unicode

如何有效处理这些包含了各种语言的丰富多样的文本数据呢?
Unicode,它收集了这个世界上所有的符号系统,包括重音符号或其他变音符号,制表符和回车符,还有很多神秘的符号,每个符号都分配一个唯一的Unicode码点,Unicode码点对应Go语言中的rune整数类型。(rune是int32等价类型)
我们可以将一个符文序列表示一个int32序列。编码方式:UTF-32或UCS-4,这种方式比较简单统一,但是它会浪费很多存储空间。
大数据计算机可读的文本是ASCII字符,本来每个ASCII字符只需要8bit或1字节就能表示。常用的字符也远少于65536,16bit编码方式就能表达常用字符。

3.5.3 UTF-8

UTF8是一个将Unicode码点编码为字节序列的变长编码。UTF8编码使用1到4个字节来表示每个Unicode码点,ASCII部分字符只使用1个字节,常用字符部分使用2或3个字节表示。
每个符号编码后第一个字节的高端bit位用于表示总共有多少编码个字节。
如果第一个字节的高端bit为0,则表示对应7bit的ASCII字符,ASCII字符每个字符依然是一个字节,和传统的ASCII编码兼容。
如果第一个字节的高端bit是110,则说明需要2个字节;后续的每个高端bit都以10开头
在这里插入图片描述
变长的编码无法直接通过索引来访问第n个字符,但有优点:

  • UTF8编码比较紧凑,完全兼容ASCII码,并且可以自动同步
  • 它可以通过向前回溯最多2个字节就能确定当前字符编码的开始字节的位置
  • 前缀编码,当从左向右解码时不会有任何歧义也并不需要向前查看。
  • 没有任何字符的编码是其他字符编码的子串,或是其他编码序列的字符,因此搜索一个字符时只要搜索它的字节编码序列即可。
  • UTF8编码的顺序和Unicode码点的顺序一致,可以直接排序UTF8编码序列。
  • 没有嵌入NUL(0)字节,可以很好兼容那些使用NUL作为字符串结尾的编程语言。

Go语言的源文件采用UTF8编码,并且Go语言处理UTF8编码的文本也很出色。unicode包提供了诸多处理rune字符相关功能的函数(区分字母和数组、字母的大写和小写转换),unicode/utf8包提供了用于rune字符序列的UTF8编码和解码的功能。
Unicode转义字符让我们可以通过Unicode码点输入特殊的字符。有两种形式:\uhhh对应16bit的码点值,\Uhhhhhhhh对应32bit的码点值,其中h是一个十六进制数组,一般很少使用32bit的形式。每一个对应码点的UTF8编码。
下面的字母串面值都表示相同的值:
在这里插入图片描述
Unicode转义也可以使用在rune字符中。下面三个字符是等价的:

在这里插入图片描述
对于小于256码点值可以写在一个十六进制转义字节中,例如\x41对应字符’A’,但对于更大码点则必须使用\u或\U转义形式。
得益于UFT8编码优良的设计,诸多字符串操作都不需要解码操作。
不用解码直接测试一个字符串是否是另一个字符串的前缀:

func HasPrefix(s,prefix string) bool{
	return len(s)>=len(prefix)&&s[:len(prefix)]==prefix
}

后缀测试:

func HasSuffix(s,suffix string) bool{
	return len(s)>=len(suffix)&&s[len(s)-len(suffix):]==suffix
}

包含子串测试:

func Contains(s,substr string) bool{
	for i:=0;i<len(s);i++{
		if HasPrefix(s[i:],substr){
			return true
		}
	}
	return false
}

对于UTF8编码后文本的处理和原始的字节处理逻辑是一样的。
内存表示形式

import "unicode/utf8"

s:="Hello, 世界"
fmt.Println(len(s))//13字节
fmt.Println(utf8.RuneCountInString(s))//9个Unicode

为了处理这些真实的字符,我们需要一个UFT8解码器。

for i := 0; i < len(s); {
	//	返回字符本身,字符采用UTF8编码后的编码字节数目
    r, size := utf8.DecodeRuneInString(s[i:])
    fmt.Printf("%d\t%c\n", i, r)
    i += size
}

在这里插入图片描述
Go语言的range循环在处理字符串时,会自动隐式解码UFT8字符串。

for i, r := range "Hello, 世界" { 
	fmt.Printf("%d\t%q\t%d\n", i, r, r)
}

统计字符串中字符的数目:

n := 0
for _, _ = range s {
	n++ 
}
n := 0
for range s {
	n++ 
}

utf8.DecodeRuneInString解码或在range循环中隐式地解码,如果遇到一个错误的UTF8编码输入,将生成Unicode字符\uFFD
UTF8字符串作为交换格式是非常方便的,但是在程序内部采用rune序列可能更方便,rune大小一致,支持数组索引和方便切割。
将[]rune类型转换应用到UTF8编码的字符串,将返回字符串编码的Unicode码点序列:

// "program" in Japanese katakana
s := "プログラム"
//%x参数用于在每个十六进制数字前插入一个空格
fmt.Printf("% x\n", s) // "e3 83 97 e3 83 ad e3 82 b0 e3 83 a9 e3 83 a0" r := []rune(s)
fmt.Printf("%x\n", r) // "[30d7 30ed 30b0 30e9 30e0]"
//如果将一个[]rune类型的Unicode字符slice或数组转为string,则对它们进行UTF8编码
fmt.Println(string(r)) // "プログラム"
//将一个整数转型为字符串:生成以只包含对应Unicode码点字符的UTF8字符串
fmt.Println(string(65)) // "A", not "65"
fmt.Println(string(0x4eac)) // "京"

3.5.4 字符串和Byte切片

  • strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能
  • bytes包,针对[]byte类型提供很多类似功能的函数。字符串是只读的,逐步构建字符串会导致很多分配和复制。bytes.Buffer类型将会更有效
  • strconv包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换
  • unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能,用于字符分类。每个函数有一个单一的rune类型的参数,然后返回一个布尔值。

basename函数
basename(s) 将看起来像是系统路径的前缀删除,同时将看似文件类型的后缀名部分删除

fmt.Println(basename("a/b/c.go")) // "c"
fmt.Println(basename("c.d.go"))   // "c.d"
fmt.Println(basename("abc"))      // "abc"

basename1.go

func basename(s string) string {
    // Discard last '/' and everything before.
    for i := len(s) - 1; i >= 0; i-- {
        if s[i] == '/' {
			s = s[i+1:]
			break
		}
	}
    // Preserve everything before last '.'.
    for i := len(s) - 1; i >= 0; i-- {
        if s[i] == '.' {
			s = s[:i]
			break
		}
	}
	return s 
}

basename2.go

func basename(s string) string {
    slash := strings.LastIndex(s, "/") // -1 if "/" not found
    s = s[slash+1:]
    if dot := strings.LastIndex(s, "."); dot >= 0 {
		s = s[:dot] 
	}
	return s 
}

一个字节slice的元 素则可以自由地修改
字符串和字节slice之间可以相互转换:

s := "abc"
//分配了一个新的字节数组用于保存字符串数据的拷贝,然后 引用这个底层的字节数组
b := []byte(s)
//构造一个字符串拷贝,以确保s2字符串是只读的
s2 := string(b)

为了避免转换中不必要的内存分配,bytes包和strings同时提供了许多实用函数。下面是 strings包中的六个函数:

func Contains(s, substr string) bool
func Count(s, sep string) int
func Fields(s string) []string
func HasPrefix(s, prefix string) bool
func Index(s, sep string) int
func Join(a []string, sep string) string

bytes包中也对应的六个函数:

func Contains(b, subslice []byte) bool
func Count(s, sep []byte) int
func Fields(s []byte) [][]byte
func HasPrefix(s, prefix []byte) bool
func Index(s, sep []byte) int
func Join(s [][]byte, sep []byte) []byte

它们之间唯一的区别是字符串类型参数被替换成了字节slice类型的参数。
bytes包还提供了Buffer类型用于字节slice的缓存。一个Buffer开始是空的,但是随着string、 byte或[]byte等类型数据的写入可以动态增长,一个bytes.Buffer变量并不需要初始化,因为零值也是有效的。

3.5.5 字符串和数字的转换

由strconv包提供字符串和数值之间的转换
将一个整数转为字符串,一种方法是用fmt.Sprintf返回一个格式化的字符串;另一个方法是用strconv.Itoa(“整数到ASCII”):

x := 123
y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv.Itoa(x)) // "123 123"

FormatInt和FormatUint函数可以用不同的进制来格式化数字:

fmt.Println(strconv.FormatInt(int64(x), 2)) // "1111011"

fmt.Printf函数的%b、%d、%o和%x等参数提供功能往往比strconv包的Format函数方便很 多,特别是在需要包含附加额外信息的时候:

s := fmt.Sprintf("x=%b", x) // "x=1111011"

如果要将一个字符串解析为整数,可以使用strconv包的Atoi或ParseInt函数,还有用于解析无 符号整数的ParseUint函数:

x, err := strconv.Atoi("123")             // x is an int
//第三个参数是用于指定整型数的大小;例如16表示int16,0则表示int。
y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits

fmt.Scanf来解析输入的字符串和数字,特别是当字符串和数字混合在一行的 时候,它可以灵活处理不完整或不规则的输入。

3.6 常量

常量表达式的值在编译器计算,而不是在运行期

 const pi = 3.14159 // approximately; math.Pi is a better approximation

批量声明多个

const (
	e = 2.71828182845904523536028747135266249775724709369995957496696763 
	pi = 3.14159265358979323846264338327950288419716939937510582097494459
)

常量可以是构成类型的一部分,例如用于指定数组类型的长度:

const IPv4Len = 4
// parseIPv4 parses an IPv4 address (d.d.d.d).
func parseIPv4(s string) IP {
    var p [IPv4Len]byte
    // ...
}

一个常量的声明也可以包含一个类型和一个值,但是如果没有显式指明类型,那么将从右边的表达式推断类型。

const noDelay time.Duration = 0
const timeout = 5 * time.Minute
fmt.Printf("%T %[1]v\n", noDelay)     // "time.Duration 0"
fmt.Printf("%T %[1]v\n", timeout)     // "time.Duration 5m0s"
fmt.Printf("%T %[1]v\n", time.Minute) // "time.Duration 1m0s"

如果是批量声明的常量,除了第一个外其它的常量右边的初始化表达式都可以省略,如果省略初始化表达式则表示使用前面常量的初始化表达式写法,对应的常量类型也一样的

const ( 
	a=1
	b 
	c=2 
	d
)
fmt.Println(a, b, c, d) // "1 1 2 2"

3.6.1 iota常量生成器

常量声明可以使用iota常量生成器初始化,它用于生成一组以相似规则初始化的常量,但是不 用每行都写一遍初始化表达式。在一个const声明语句中,在第一个声明的常量所在的行, iota将会被置为0,然后在每一个有常量声明的行加一。

type Weekday int
const (
    Sunday Weekday = iota//0
    Monday //1
    Tuesday //2
    Wednesday
    Thursday
    Friday
    Saturday
)

例子:给一个无符号整数的最低5bit的每个bit指定一个名字:

type Flags uint
const (
    FlagUp Flags = 1 << iota // is up
	FlagBroadcast// supports broadcast access capability
	FlagLoopback// is a loopback interface
	FlagPointToPoint// belongs to a point-to-point link
	FlagMulticast// supports multicast access capability
)

随着iota的递增,每个常量对应表达式1 << iota,是连续的2的幂,分别对应一个bit位置
iota局限性:它并不能用于产生1000的幂(KB、MB等),因 为Go语言并没有计算幂的运算符。

3.6.2 无类型常量

六种未明确类型的常量类型:无类型的布尔型、无类型的整数、无类型的字符、无类型的浮点数、无类型的复数、无类型的字符串
通过延迟明确常量的具体类型,无类型的常量不仅可以提供更高的运算精度,而且可以直接 用于更多的表达式而不需要显式的类型转换。
只有常量可以是无类型的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/52426.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用Spring Boot AOP实现日志记录

目录 介绍 1.1 什么是AOP 1.2 AOP体系与概念 AOP简单实现 2.1 新建一个SpringBoot项目&#xff0c;无需选择依赖 2.2 设置好本地Maven配置后&#xff0c;在pom.xml文件里添加添加maven依赖 2.3 创建一个业务类接口 2.4 在实体类实现接口业务 2.5 在单元测试运行结果 …

python中的单引号、双引号和多引号

目录 python中的单引号 python中的双引号 python中的多引号 三者分别在什么时候使用&#xff0c;有什么区别 总结 python中的单引号 在Python中&#xff0c;单引号&#xff08;&#xff09;可以用来表示字符串。 可以使用单引号创建一个简单的字符串&#xff0c;例如&…

第1章 JavaScript简史

JavaScript的起源 JavaScript是Netscape公司与Sun公司合作开发的在JavaScript诞生之前游览器就是显示超文本文档的简单的软件&#xff0c;JavaScript为此增加了交互行为ECMAScript是JavaScript的标准化&#xff0c;本质上是同一个语言JavaScript是一门脚本语言通常只能运行在游…

仿VScode MDK背景配色方案

效果如果所示 操作方法&#xff1a;备份后修改~/UV4文件夹下的global.prop&#xff0c;用以下的代码代替。 # properties for all file types indent.automatic1 virtual.space0 view.whitespace0 view.endofline0 code.page936 caretline.visible1 highlight.matchingbraces1…

【数据结构】队列(Queue)的实现 -- 详解

一、队列的概念及结构 1、概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out)。 入队列&#xff1a;进行插入操作的一端称为队尾。 出队列&#xff1a;进行删除操作的…

当ChatGPT应用在汽车行业,具体有哪些场景?

​ ChatGPT有潜力彻底改变汽车行业并将其提升到新的高度。在ChatGPT的加持下&#xff0c;该行业的多个领域都将取得重大变化。 利用ChatGPT作更高级的虚拟助理 你可能用过现有的虚拟助理&#xff0c;它们一系列的回复有时候让人不得不感叹一句“人工智障”&#xff01;然而&a…

Android Glide预处理preload原始图片到成品resource 预加载RecyclerViewPreloader,Kotlin

Android Glide预处理preload原始图片到成品resource & 预加载RecyclerViewPreloader&#xff0c;Kotlin <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_MED…

RT1052的定时器

文章目录 1 通用定时器1.1 定时器框图1.2 实现周期性中断 2 相关寄存器3 定时器配置3.1 时钟使能3.2 初始化GPT1定时器3.2.1 base3.2.2 initConfig3.2.2.1 clockSorce3.2.2.2 divider3.2.2.3 enablexxxxx 3.3 设置 GPT1 比较值3.3.1 base3.3.2 channel3.3.3 value 3.4 设置 GPT…

合并两个有序数组——力扣88

文章目录 题目描述法一 双指针法二 逆向双指针 题目描述 法一 双指针 使用双指针方法&#xff0c;将两个数组看作队列&#xff0c;每次从两个数组头部取出比较小的数字放到结果中。 void merge(vector<int>&nums1, int m,vector<int>&nums2, int n){int p1…

什么是DOTS?

(图片为实机测试) DOTS全称&#xff1a;&#xff08;Burst Job SystemEntity Component System&#xff09; 新型高性能、多线程面向数据的技术堆栈 是由&#xff1a;BrustJob System ECS组合而成&#xff0c;是一种面向数据对象的编程体系&#xff0c;在unity中您也可以对…

Psim 2022电力仿真--锁相环控制程序

目录 目录 1.原理 2.代码实现 3.仿真实现 4.仿真结果 5.讨论 1.原理 三相锁相环是一种用于控制交流&#xff08;AC&#xff09;信号的相位、频率和波形的电路&#xff0c;其原理和应用也广泛用于电源领域。使用三相锁相环可以使交流电源输出的电压稳定、精准地与输入信号…

如何降低TCP在局域网环境下的数据传输延迟

以Ping为例。本案例是一个测试题目&#xff0c;只有现象展示&#xff0c;不含解决方案。 ROS_Kinetic_26 使用rosserial_windows实现windows与ROS master发送与接收消息_windows 接收ros1 消息 什么是ping&#xff1f; AI&#xff1a; ping是互联网控制消息协议&#xff08;…

国内 github.com经常打不开的解决办法

1、打开网站http://tool.chinaz.com/dns/ 2、在A类型中填写github.com,再点击监测按钮 3、复制下面任意一个ip 4、打开电脑文件C:\Windows\System32\drivers\etc下的host文件 5、在host文件的最后一刚加入刚才复制的IP 6、重新打开GitHub

tensorRT模型性能测试

目录 前言1. 模型训练1.1 模型1.2 数据集1.3 xml2yolo1.4 yolo2json1.5 json2yolo1.6 训练 2. TRT模型转换2.1 YOLOv5 ONNX导出2.2 YOLOv6 ONNX导出2.3 YOLOv5 engine生成2.4 YOLOv6 engine生成 3. TRT模型测试3.1 YOLOv5 engine mAP测试3.2 YOLOv5 engine 速度测试3.3 YOLOv6 …

第120天:免杀对抗-防朔源防流量防特征CDN节点SSL证书OSS存储上线

知识点 #知识点&#xff1a; 1、CS-CDN节点-防拉黑 2、CS-SSL证书-防特征 3、CS-OSS存储-防流量#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指令-资源 代码加载面-D…

【ARM】内核驱动之设备树的学习-长文

❤️作者主页:凉开水白菜 ❤️作者简介:共同学习,互相监督,热于分享,多加讨论,一起进步! ❤️点赞 👍 收藏 ⭐再看,养成习惯 订阅的粉丝可通过PC端文末加我微信,可对文章的内容进行一对一答疑! 文章目录 一、什么是设备树,为什么叫设备树?二、如何编译设备树?三、…

【语音控制SU-03T的使用】

语音控制SU-03T的使用 最近入手了SU-03T型号的语音模块&#xff0c;下面记录一下使用方式。相对于LD3320语音模块来说SU-03T更智能、使用更方便&#xff0c;从价格来讲也相对便宜&#xff0c;需要的可以在淘宝自行购买。 引脚详解一、智能公元/AIOT产品化平台配置 智能公元链接…

React井字棋游戏官方示例

在本篇技术博客中&#xff0c;我们将介绍一个React官方示例&#xff1a;井字棋游戏。我们将逐步讲解代码实现&#xff0c;包括游戏的组件结构、状态管理、胜者判定以及历史记录功能。让我们一起开始吧&#xff01; 项目概览 在这个井字棋游戏中&#xff0c;我们有以下组件&am…

【数据预测】基于蜣螂优化算法DBO的VMD-KELM光伏发电功率预测 短期功率预测【Matlab代码#53】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】1. 蜣螂优化算法DBO2. 变分模态分解VMD3. 核极限学习机KELM4. 部分代码展示5. 仿真结果展示6. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】 1. 蜣螂…

Vulnhub: hacksudo: search靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.170 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.170 80端口目录爆破 feroxbuster -k -d 1 --url http://192.168.111.170 -w /opt/zidian/SecLists-2022.2/Discovery/Web…