📅 2024年4月27日

📦 使用版本为 1.21.5

Go的数据类型

📖官方文档:https://go.dev/ref/spec#Types

1️⃣ 布尔类型

⭐️ 布尔类型只有 ,truefalse

⭐️ 在 Go中整数0不会代表假,非零整数也不能代替真,也就是数字并不能代替布尔类型在逻辑判断中使用

2️⃣ 整形

⭐️ 在 Go中它是有无符号数的,但是在 Java中他就没有无符号数的

无符号数和有符号数区别就在于,无符号数不可以表示负数

序号 类型和描述
uint8 无符号 8 位整型
uint16 无符号 16 位整型
uint32 无符号 32 位整型
uint64 无符号 64 位整型
int8 有符号 8 位整型
int16 有符号 16 位整型
int32 有符号 32 位整型
int64 有符号 64 位整型
uint 无符号整型 至少32位
int 整型 至少32位
uintptr 等价于无符号64位整型,但是专用于存放指针运算,用于存放死的指针地址。

⭐️ 它们的取值范围

整数类型 有无符号 存储大小 (字节) 位数 表示范围
int8 有符号 1 8 -128 to 127
uint8 无符号 1 8 0 to 255
int16 有符号 2 16 -32,768 to 32,767
uint16 无符号 2 16 0 to 65,535
int32 有符号 4 32 -2,147,483,648 to 2,147,483,647
uint32 无符号 4 32 0 to 4,294,967,295
int64 有符号 8 64 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
uint64 无符号 8 64 0 to 18,446,744,073,709,551,615

请注意,intuint 的具体大小未直接列出,因为它们是根据平台而定的,通常分别与 int32int64uint32uint64 相匹配。

⭐️ unit8刚刚好可以用来表示颜色的 RGB值(0-255)

⭐️ 如果超出整数限定的范围的最大值,就会发生整数环绕

func main() {
	var a uint8 = 255
	a++
	fmt.Println(a)
	var b int8 = 127
	b++
	fmt.Println(b)
}

//输出
0
-128 

3️⃣ 浮点型

⭐️ IEEE-754浮点数

⭐️ 在 GO中没有 double这个表示关键字类型而是代替使用 float64,单精度则用 float32

⭐️ 如果声明变量的时候未声明默认就是 float64

类型 字节 类型和描述
float32 4 IEEE-754 32位浮点数
float64 8 IEEE-754 64位浮点数

4️⃣(1)字符类型

完全兼容 UTF-8

⭐️ byteuint8互换使用,runeint32互换使用,就是使用了别名

Printf 几乎和C的 printf一模一样

func main() {
	var u uint8 = 33
	var b byte = 33
	fmt.Printf("%c\n", b) //打印出字符 unicode 这个和Java类似
	fmt.Printf("%c\n", u) //打印出字符
	fmt.Printf("%v\n", b)  //打印出数字
	fmt.Printf("%v", b) 
}

//输出
!
!
33
33

⭐️ 任何整数都可以转换成对应的字符(Unicode表上有),但是如果你使用的是 rune类型这个,那就表示你的意图就是将他输为一个字符,应该是相当于 char

⭐️ 凯撒加密法(Caeser cipher):对于加密信息,一种简单有效的办法就是把每个字母都移动固定长度的位置。

func main() {
	c := 'c'
	c += 3 //往后移动三位
	fmt.Printf("%c", c)
}

⭐️ ROT13:把字母替换成+13后对应的字母

⭐️ 本质上每个 runebyte,都是存储的 数值类型,也就表示它们之间也可以运算

func main() {
	c := 'c'
	C := 'C'
	c = c - 'a' + 'A' //小写转换大写
	C = C - 'A' + 'a' //大写转换小写
	fmt.Printf("%c\n", c)
	fmt.Printf("%c", C)
}
类型 描述
byte 等价 uint8 可以表达 ANSCII字符
rune 等价 int32 可以表达Unicode字符

⭐️ unicode包,包含了一些针对测试用的函数

func main() {
	unicode.IsLetter('1') //判断是否为字母
	unicode.IsDigit('A') //判断是否为数字
	unicode.IsSpace(' ') //判断是否为空格
}

⭐️ 以下是 unicode包中常用的方法和使用方法的表格:

方法名 用途 用法示例
IsLetter 判断一个Unicode字符是否为字母 unicode.IsLetter('a')
IsDigit 判断一个Unicode字符是否为数字 unicode.IsDigit('1')
IsUpper 判断一个Unicode字符是否为大写字母 unicode.IsUpper('A')
IsLower 判断一个Unicode字符是否为小写字母 unicode.IsLower('a')
IsTitle 判断一个Unicode字符是否为标题字符(通常是大写字母) unicode.IsTitle('T')
IsSpace 判断一个Unicode字符是否为空白字符 unicode.IsSpace(' ')
IsPunct 判断一个Unicode字符是否为标点符号 unicode.IsPunct('!')
IsSymbol 判断一个Unicode字符是否为符号字符 unicode.IsSymbol('+')
IsPrint 判断一个Unicode字符是否为可打印字符 unicode.IsPrint('*')
ToLower 将一个Unicode字符转换为小写字母 unicode.ToLower('A')
ToUpper 将一个Unicode字符转换为大写字母 unicode.ToUpper('a')
ToTitle 将一个Unicode字符转换为标题形式(通常是大写字母) unicode.ToTitle('t')
ToASCII 将一个Unicode字符转换为对应的ASCII字符,如果存在的话 unicode.ToASCII('©')
FullRuneName 返回一个Unicode字符的完整名称 unicode.FullRuneName('❤')
RuneCountInString 返回字符串中特定Unicode字符的数量 unicode.RuneCountInString("hello", 'l')

4️⃣(2)字符串

⭐️ 可以赋予给不同变量不同的 string值,但是 string本身并不可变

⭐️ 字符串可以为空,但不会是 nil

⭐️ 在 go中默认 string是一个 [8]byte的一个集合,和Java一样可以通过下标来访问 String的字符,但是不能通过下标修改,因为字符串不支持取地址

func main() {
	s := "ABCD"
	fmt.Printf("%c", s[1])//输出B
}

⭐️ 和 java/python一样,两个字符串可以用 +号拼接,或者使用 +=,但是这并不是最有效的办法(后面会学到的)

⭐️ 双引号和与反单引号区别: 双引号需要对特殊字符进行转义,而反单引号则不需要

func main() {
    //两个输出都是一样
	s1:="Hi,\nthis is \"RainBowMango\"."
	s2:=`Hi,
this is "RainBowMango".`
	fmt.Println(s1)
	fmt.Println(s2)
}

⭐️ 字符串可以拼接比如 a:='a'+b' 但是会触发内存分配和拷贝,单行语句拼接多个只触发一次,先计算最终字符串长度在分配内存

⭐️ string[]byte之间可以转换,但是触发内存拷贝,会有一定的开销

5️⃣ 复数

类型 描述
complex128 64位实数和虚数
complex64 32位实数和虚数

6️⃣ 其他类型

类型 例子
数组 [5]int,长度为5的整型数组
切片 []float64,64位浮点数切片
映射表 map[string]int,键为字符串类型,值为整型的映射表
结构体 type Gopher struct{},Gopher结构体
指针 *int,一个整型指针。
函数 type f func(),一个没有参数,没有返回值的函数类型
接口 type Gopher interface{},Gopher接口
通道 chan int,整型通道

7️⃣ 零值

⭐️ 当你声明变量,但是不对他初始化,那么它的值默认就是零值 zero value,当然他不是字面上说的数字0,是声明类型的空值或者是默认值

⭐️ nil仅仅只是一个变量,下面是源码体现

Go中的 nil并不等同于其他语言的 nullnil仅仅只是一些类型的零值,并且不属于任何类型,所以 nil == nil这样的语句是无法通过编译的

var nil Type
类型 零值
数字类型 0
布尔类型 false
字符串类型 ""
数组 固定长度的对应类型的零值集合
结构体 内部字段都是零值的结构体
切片,映射表,函数,接口,通道,指针 nil

8️⃣ 类型转换

⭐️ Go语言没有自动类型提升或者自动你类型转换

image-20240428112601852

9️⃣ 拓展:

⭐️ strings包

⭐️ 在 Go中可以使用 sttings包来对字符串进行预处理

方法名 功能描述 使用示例
Compare(a, b string) 按照字典顺序比较两个字符串,返回负数、0或正数表示a小于、等于或大于b。 result := strings.Compare("abc", "def")
Contains(s, substr string) 判断字符串s是否包含子串substr,是则返回true。 hasSub := strings.Contains("hello world", "world")
ContainsAny(s, chars string) 判断字符串s是否包含chars中的任意一个字符,是则返回true。 hasAny := strings.ContainsAny("hello", "xyz")
ContainsRune(s, r rune) 判断字符串s是否包含指定的Unicode码位r,是则返回true。 hasRune := strings.ContainsRune("hello", 'e')
Count(s, sep string) 计算字符串sep在s中出现的非重叠次数,如果sep为空字符串,则返回s的长度加1。 count := strings.Count("hello hello", " ")
EqualFold(s, t string) 比较两个字符串忽略大小写,相等返回true。 equal := strings.EqualFold("Go", "go")
Fields(s string) 根据空白字符分割字符串s为[]string,比 Split更方便处理英文文本。 words := strings.Fields("one two three")
HasPrefix(s, prefix string) 判断字符串s是否以前缀prefix开始,是则返回true。 hasPrefix := strings.HasPrefix("golang", "go")
HasSuffix(s, suffix string) 判断字符串s是否以后缀suffix结束,是则返回true。 hasSuffix := strings.HasSuffix("golang", "lang")
Index(s, sep string) 返回sep在s中第一次出现的位置索引,未找到返回-1。 index := strings.Index("hello world", "world")
Join(a []string, sep string) 使用sep连接字符串切片a中的元素形成一个新的字符串。 joined := strings.Join([]string{"hello", "world"}, " ")
Repeat(s string, count int) 将字符串s重复count次后返回新的字符串。 repeated := strings.Repeat("go", 3)
Replace(s, old, new string, n int) 将s中的前n个old子串替换为new,n为-1则全部替换。 replaced := strings.Replace("banana", "a", "o", -1)
Split(s, sep string) 使用sep作为分隔符将s分割成[]string,不包括sep本身,sep为空时按Unicode字符分割。 parts := strings.Split("a,b,c", ",")
ToLower(s string) 将字符串s转换为小写形式。 lower := strings.ToLower("GO")
ToUpper(s string) 将字符串s转换为大写形式。 upper := strings.ToUpper("go")
// 以下代码演示了strings包中几个常用函数的使用方法,
// 包括检查字符串前缀、后缀,查找子串位置,替换子串,以及统计字符出现次数。

	str := "AAAAAbc" // 定义一个字符串变量

	// 检查字符串是否以指定前缀开始
	fmt.Printf("%t\n", strings.HasPrefix(str, "A"))

	// 检查字符串是否以指定后缀结束
	fmt.Printf("%t\n", strings.HasSuffix(str, "c"))

	// 查找指定子串第一次出现的位置
	fmt.Printf("%d\n", strings.Index(str, "b"))

	// 查找指定子串最后一次出现的位置
	fmt.Printf("%t\n", strings.LastIndex(str, "bc"))

	// 查找指定字符第一次出现的位置
	fmt.Printf("%d\n", strings.IndexRune(str, 'b'))

	// 将字符串中第一个指定的子串替换为另一个子串
	fmt.Printf("%s\n", strings.Replace(str, "b", "B", 1))

	// 统计字符串中指定字符出现的次数
	fmt.Printf("%d\n", strings.Count(str,"A"))
// 以下代码演示了strings包中几个常用函数的使用方法,
// 包括检查字符串前缀、后缀,查找子串位置,替换子串,以及统计字符出现次数。

	str := "AAAAAbc" // 定义一个字符串变量

	// 检查字符串是否以指定前缀开始
	fmt.Printf("%t\n", strings.HasPrefix(str, "A"))

	// 检查字符串是否以指定后缀结束
	fmt.Printf("%t\n", strings.HasSuffix(str, "c"))

	// 查找指定子串第一次出现的位置
	fmt.Printf("%d\n", strings.Index(str, "b"))

	// 查找指定子串最后一次出现的位置
	fmt.Printf("%t\n", strings.LastIndex(str, "bc"))

	// 查找指定字符第一次出现的位置
	fmt.Printf("%d\n", strings.IndexRune(str, 'b'))

	// 将字符串中第一个指定的子串替换为另一个子串
	fmt.Printf("%s\n", strings.Replace(str, "b", "B", 1))

	// 统计字符串中指定字符出现的次数
	fmt.Printf("%d\n", strings.Count(str,"A"))

⭐️ strconv包

💡 字符串的相关类型转换都是通过 strcon包实现

当然,下面是Go语言 strconv包中一些常用方法的概览,包括它们的功能描述和简单的使用示例。为了清晰展示,我采用Markdown格式列出:

方法名 功能描述 使用示例
Atoi(s string) (int, error) 将字符串s转换为整数(int类型),s应代表一个有符号的十进制整数。 num, err := strconv.Atoi("123")
Itoa(i int) string 将整数i转换为表示该整数的字符串。 str := strconv.Itoa(123)
ParseInt(s string, base int, bitSize int) (i int64, err error) 解析一个表示整数的字符串并返回其值和错误。base指定了数字的基数(2到36),bitSize指定了整数类型。 num, err := strconv.ParseInt("123", 10, 64)
ParseUint(s string, base int, bitSize int) (uint64, error) ParseInt类似,但用于无符号整数。 num, err := strconv.ParseUint("123", 10, 64)
FormatInt(i int64, base int) string 将整数i格式化为给定基数(base,2到36)的字符串表示。 str := strconv.FormatInt(123, 10)
FormatUint(i uint64, base int) string FormatInt类似,但用于无符号整数。 str := strconv.FormatUint(123, 10)
ParseBool(str string) (value bool, err error) 解析一个表示布尔值的字符串并返回其布尔值。有效值为"1", "t", "T", "true", "TRUE", "True" 或 "0", "f", "F", "false", "FALSE", "False"。 boolValue, err := strconv.ParseBool("true")
AppendQuote(dst []byte, s string) []byte 将带有引号的s追加到dst,并对内部引号进行转义,返回修改后的dst。 buf := make([]byte, 0)
result := strconv.AppendQuote(buf, "He said, \"Hello\"!")
AppendQuoteRune(dst []byte, r rune) []byte 类似于 AppendQuote,但用于单个rune字符。 buf := make([]byte, 0)
result := strconv.AppendQuoteRune(buf, '"')

这些只是 strconv包中的一部分方法,实际包中还包含了更多用于处理不同数值和类型转换的功能。在实际使用时,请根据需要查阅Go语言官方文档获取最准确的信息和最新方法列表。