Golang之数据类型

Golang之数据类型写在前面:每个开发语言的数据类型都大同小异,在Golang中,通过数据类型声明函数和变量,总体来说数据类型标识了程序运行时所需内存空间大小,合适的类型声明可以提高内存利用率。0x01 数据类型Golang中数据类型比较多,下面会通过示

大家好,欢迎来到IT知识分享网。

写在前面:

每个开发语言的数据类型都大同小异,在Golang中,通过数据类型声明函数和变量,总体来说数据类型标识了程序运行时所需内存空间大小,合适的类型声明可以提高内存利用率。

0x01 — 数据类型

Golang中数据类型比较多,下面会通过示例展示下:

1. 布尔类型

布尔类类型标识为bool, 其值为 true或false,定义使用如下:

package test import ( "fmt" "testing" "time" ) func TestBoolType(t *testing.T) { var b, c, d, e bool ct := time.Now().Unix() // 获取时间戳 t.Log("当前时间戳:", ct) b = false c = true e = ct < 1616 // 如果运算结果是一个bool也可以给bool类型赋值 //e = 12 + 12 // 报错:cannot use 12 + 12 (type untyped int) as type bool in assignment t.Log("b:", b) t.Log("c:", c) t.Log("d:", d) //为赋值默认为false t.Log("e:", e) }

输出:

=== RUN TestBoolType data_type_test.go:12: 当前时间戳:  data_type_test.go:19: b: false data_type_test.go:20: c: true data_type_test.go:21: d: false data_type_test.go:22: e: false --- PASS: TestBoolType (0.00s) PASS

2. 数字类型

数字类型有很多种,重点说下整数及运算方式:

package test import ( "testing" "time" ) // 加法、减法、乘法、除法、取余、左移、右移、异或 运算 func operation( t *testing.T, a, b int) { t.Logf("输入参数:[%d],[%d]", a, b) t.Log("加法运算结果:", a + b) t.Log("减法运算结果:", a - b) t.Log("乘法运算结果:", a * b) t.Log("除法运算结果:", a / b) t.Log("整除取余结果:", a % b) t.Log("左移运算结果:", a << b) // 0010 << 1 -> 0100 t.Log("右移运算结果:", a >> b) // 0010 >> 1 -> 0001 t.Log("异或运算结果:", a ^ b) // 0010 ^ 0001 -> 0011 } /* 测试整形类型 */ func TestDataType(t *testing.T) { var i, j int i, j = 2, 1 operation(t, i, j) }

输出:

=== RUN TestDataType data_type_test.go:44: i:2, j:1 data_type_test.go:27: 输入参数:[2],[1] data_type_test.go:28: 加法运算结果: 3 data_type_test.go:29: 减法运算结果: 1 data_type_test.go:30: 乘法运算结果: 2 data_type_test.go:31: 除法运算结果: 2 data_type_test.go:32: 整除取余结果: 0 data_type_test.go:33: 左移运算结果: 4 data_type_test.go:34: 右移运算结果: 1 data_type_test.go:35: 异或运算结果: 3 --- PASS: TestDataType (0.00s) PASS

以上代码注意点:

  • Golang中 ++ 和 –在以上代码中没有体现,原因是 i++或者i–是语句而非表达式,语句的意思是会对++或–前面的变量进行处理,而不会有任何返回值。所以我们可以在条件语句中使用,改变的是变量指向的地址内存的值。同时没有–i 或者++i这种操作。
  • int和uint型在不同位操作系统所代表的长度是不同的,在32位操作系统上,它们均使用 32 位(4 个字节),在 64 位操作系统上,它们均使用 64 位(8 个字节)

除了int型外,Golang还有下面的数字类型:

// 有符号整数 int8(-128 -> 127) int16(-32768 -> 32767) int32(-2,147,483,648 -> 2,147,483,647) int64(-9,223,372,036,854,775,808 -> 9,223,372,036,854,775,807) // 无符号整数 uint8(0 -> 255) uint16(0 -> 65,535) uint32(0 -> 4,294,967,295) uint64(0 -> 18,446,744,073,709,551,615) // 浮点型 float32(+- 1e-45 -> +- 3.4 * 1e38) float64(+- 5 1e-324 -> 107 1e308) // 复数 Golang 拥有以下复数类型: complex64 (32 位实数和虚数) complex128 (64 位实数和虚数) 复数使用 re+imI 来表示,其中 re 代表实数部分, im 代表虚数部分,I 代表根号负 1 var c1 complex64 = 5 + 10i fmt.Printf("The value is: %v", c1) // 输出: 5 + 10i

注意:

整型的默认值和零值为 0,浮点型的默认值和零值为 0.0。默认值表示声明为赋值的变量

在开发过程中大部分情况使用的是int型,int 型是计算速度最快的一种类型

如果使用浮点型时尽量使用float64, 保证精度同时科学计算函数math会需要这个精度

Golang是强类型语言,不支持隐形类型转换。

3. uintptr类型

uintptr是Golang中的整数类型,能够存储指针值的无符号整数,实际是通过一个uint(无符号整形)来表示地址。

和通用行指针unsafe.Pointer的区别后面在讲, 此处会设计到不安全编程里面的unsafe包。

4. 字符类型

字符在Golang中是通过整数表示的展示形式而已,每个字符都可以通过整数形式来表示:

package test import ( "reflect" "testing" "time" ) // 字符类型 func TestString(t *testing.T) { // byte var s string s = "hello go" var sb []byte = []byte(s) // 字符串转数组 var ss string = string(sb) // 数组转字符串 var s1 byte = 'h' var s2 byte = 66 t.Logf("sb的值%v",sb) // 格式化打印后面会在学习fmt包时详解,当前%v表示默认格式输出 t.Logf("ss的值%v",ss) t.Logf("s1的值%v",s1) t.Logf("s2的值%v",s2) // rune var ch int = '\u0041' var ch2 int = '\u03B2' var ch3 int = '\U00' t.Logf("%d - %d - %d\n", ch, ch2, ch3) // %d 打印整形 t.Logf("%c - %c - %c\n", ch, ch2, ch3) // %c 打印相应Unicode码点所表示的字符 t.Logf("%X - %X - %X\n", ch, ch2, ch3) // %X 打印十六进制表示,字母形式为大写 A-F t.Logf("%U - %U - %U\n", ch, ch2, ch3) // %U 打印Unicode格式:U+1234,等同于 "U+%04X" var teststr = "你好啊,go" t.Log("通过byte处理字符串", []byte(teststr)) t.Log("通过rune处理字符串", []rune(teststr)) // 通过byte和rune处理单字节ascii效果是一样的,但是处理多字节就会不通, // 因为rune能处理更大的字节数,因为Go语言中默认是用UTF-8类型, // UTF-8类型是三个16进制表示,所以是三字节,输出的结果正好是byte处理的 // 没三个数据合并成一个。 }

输出:

=== RUN TestString data_type_test.go:20: sb的值[104 101 108 108 111 32 103 111] data_type_test.go:21: ss的值hello go data_type_test.go:22: s1的值104 data_type_test.go:23: s2的值66 data_type_test.go:29: 65 - 946 -  data_type_test.go:30: A - β - data_type_test.go:31: 41 - 3B2 -  data_type_test.go:32: U+0041 - U+03B2 - U+ data_type_test.go:35: 通过byte处理字符串 [228 189 160 229 165 189 229 149 138 239 188 140 103 111] data_type_test.go:36: 通过rune处理字符串 [20320 22909 21834 65292 103 111] --- PASS: TestString (0.00s) PASS

以上代码注意:

byte类型是uint8的别名,byte会表示单字节数据ascii字符,[]byte可以表示字符串,

rune类型是int32的别名,rune用来表示多字节数据unicode或utf-8字符,

Unicode 至少占用 2 个字节,Go会使用int类型或者int16类型来表示,在使用\u前缀表示后面是2字节(长度为4的16进制数),如果前缀为\U则表示后面是4字节(长度为8的16进制数)

0x02 — 字符串

字符串是 UTF-8 字符的一个序列(当字符为 ASCII 码时则占用 1 个字节,其它字符根据需要占用 2-4 个字节),字符串在GoLang内存模型中用两个字节长度表示结构,包含一个指向存储的指针,和一个长度数据。

struct String { byte* str; intgo len; };

需要注意:

字符串是一种值类型,且值不可变,所以多字符串共享同一个存储数据是安全的。

字符串是可进行切分操作str[i:j],切分后会得到一个新的2字长结构,指针字段指向同一个字节序列,长度表示新字符串的长度,所以字符串切分不涉及内存的重新分配

字符串类型的零值为指针为nil,len为0的字符串,即空字符串 “”

获取字符串中某个字节的地址的行为是非法的,例如: &s[1],会存在异常:Cannot take the address of ‘s[1]

0x03 — 总结

数据类型是Golang入门的基础,需要搞明白,但是有些不常用的类型比如complex128等可以先不用了解,如果不做数据分析工作应该很少会用到。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/86784.html

(0)
上一篇 2024-10-03 22:26
下一篇 2024-10-05 18:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信