📅 2024年4月27日
📦 使用版本为1.21.5
Go的数据类型
📖官方文档:https://go.dev/ref/spec#Types
1️⃣ 布尔类型
⭐️ 布尔类型只有真
和假
,true
和false
⭐️ 在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 |
请注意,int
和 uint
的具体大小未直接列出,因为它们是根据平台而定的,通常分别与 int32
或 int64
、uint32
或 uint64
相匹配。
⭐️ 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
⭐️ byte
和uint8
互换使用,rune
和int32
互换使用,就是使用了别名
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后对应的字母
⭐️ 本质上每个rune
和byte
,都是存储的数值
类型,也就表示它们之间也可以运算
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
并不等同于其他语言的null
,nil
仅仅只是一些类型的零值,并且不属于任何类型,所以nil == nil
这样的语句是无法通过编译的
var nil Type
类型 | 零值 |
---|---|
数字类型 | 0 |
布尔类型 | false |
字符串类型 | "" |
数组 | 固定长度的对应类型的零值集合 |
结构体 | 内部字段都是零值的结构体 |
切片,映射表,函数,接口,通道,指针 | nil |
8️⃣ 类型转换
⭐️ Go语言没有自动类型提升或者自动你类型转换
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语言官方文档获取最准确的信息和最新方法列表。
未经允许禁止转载