文章

基本数据类型

1.整型

Go语言同时提供了有符号和无符号的整数类型。

  • 有符号整型:int、int8、int64、int32、int64
  • 无符号整型:uint、uint8、uint64、uint32、uint64、uintptr

有符号整型范围:-2^(n-1) 到 2^(n-1)-1

无符号整型范围: 0 到 2^n-1

实际开发中由于编译器和计算机硬件的不同,int 和 uint 所能表示的整数大小会在 32bit 或 64bit 之间变化

用来表示 Unicode 字符的 rune 类型int32 类型是等价的,通常用于表示一个 Unicode 码点。这两个名称可以互换使用;

同样,byteuint8 也是等价类型,byte 类型一般用于强调数值是一个原始的数据而不是一个小的整数

无符号的整数类型 uintptr,它没有指定具体的 bit 大小但是足以容纳指针。uintptr 类型只有在底层编程时才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。

2.浮点型

var 变量名 float32/float64

  1. float32 :范围 约1.4e-45 到 约3.4e38;单精度浮点数,占用32位(4字节);其中1位用于符号位,8位用于指数,剩余的23位用于尾数
  2. float64 :范围约4.9e-324 到 约1.8e308;双精度浮点数,占用64位(8字节);其中1位用于符号位,11位用于指数,剩余的52位用于尾数

3.布尔型

var 变量名 bool

==,>,<<=, >=,&&(AND),||(OR)等都会产生bool值

&&(AND),||(OR)是具有短路行为的,如果运算符左边的值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值。(&&优先级高于||)

布尔型数据只有true和false,且不能参与任何计算以及类型转换

4.字符类型

Go语言的字符有以下两种:

  • 一种是 uint8 类型,或者叫 byte 型,代表了 ASCII 码的一个字符。
  • 另一种是 rune 类型,代表一个 UTF-8 字符,当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型。rune 类型等价于 int32 类型。

byte 类型是 uint8 的别名,rune 类型是int32的别名

ASCII 码的一个字符占一个字节

ASCII 定义 128 个字符,由码位 0 – 127 标识。它涵盖英文字母,拉丁数字和其他一些字符

5.字符串型

var 变量名 string

字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容。

当字符为 ASCII 码表上的字符时则占用 1 个字节

字符串中可以使用转义字符来实现换行、缩进等效果,常用的转义字符包括:

  1. \n:换行符
  2. \r:回车符
  3. \t:tab 键
  4. \u 或 \U:Unicode 字符
  5. \:反斜杠自身

如果使用``反引号,会被原样进行赋值和输出

5.1 字符串的应用

一般的比较运算符(==、!=、<、<=、>=、>)是通过在内存中按字节比较来实现字符串比较的,因此比较的结果是字符串自然编码的顺序。

字符串所占的字节长度可以通过函数 len() 来获取,例如 len(str)。

字符串的内容(纯字节)可以通过标准索引法来获取,在方括号[ ]内写入索引,索引从 0 开始计数:

  • 字符串 str 的第 1 个字节:str[0]
  • 第 i 个字节:str[i - 1]
  • 最后 1 个字节:str[len(str)-1]

⚠️:获取字符串中某个字节的地址属于非法行为,例如 &str[i]

5.1.1 字符串拼接符“+”

两个字符串 s1 和 s2 可以通过 s := s1 + s2 拼接在一起。将 s2 追加到 s1 尾部并生成一个新的字符串 s

str := "第一部分 " + "第二部分"

也可以使用“+=”来对字符串进行拼接:

s := "hel" + "lo,"
s += "world!"
fmt.Println(s) //输出 “hello, world!”

除了使用+进行拼接,我们也可以使用WriteString()

    str1 := "你好,"
    str2 := "我是yama"
    var stringBuilder bytes.Buffer
    //节省内存分配,提高处理效率
    stringBuilder.WriteString(str1)
    stringBuilder.WriteString(str2)
    fmt.Println(stringBuilder.String()) // 你好,我是yama

5.1.2 遍历

unicode字符集使用for range进行遍历,ascii字符集可以使用for range或者for循环遍历

	var str1 string = "hello"
	var str2 string = "hello,我是yama"
	// 遍历
	for i := 0; i < len(str1); i++ {
		fmt.Printf("ascii: %c %d\n", str1[i], str1[i])
	}
	for _, s := range str1 {
		fmt.Printf("unicode: %c %d\n ", s, s)
	}
	// 中文只能用 for range
	for _, s := range str2 {
		fmt.Printf("unicode: %c %d\n ", s, s)
	}
//ascii: h 104
//ascii: e 101
//ascii: l 108
//ascii: l 108
//ascii: o 111
//unicode: h 104
//unicode: e 101
//unicode: l 108
//unicode: l 108
//unicode: o 111
//unicode: h 104
//unicode: e 101
//unicode: l 108
//unicode: l 108
//unicode: o 111
//unicode: , 44
//unicode: 我 25105
//unicode: 是 26159
//unicode: y 121
//unicode: a 97
//unicode: m 109
//unicode: a 97

5.1.3 字符串的格式化

  • print : 结果写到标准输出
  • Sprint:结果会以字符串形式返回
%c  单一字符
%T  动态类型
%v  本来值的输出
%+v 字段名+值打印
%d  十进制打印数字
%p  指针,十六进制
%f  浮点数
%b  二进制
%s string

5.1.4 字符串查找

  • strings.Index(): 正向搜索子字符串
  • strings.LastIndex():反向搜索子字符串
	// 查找
	tracer := "张三来了,张三bye bye"
	// 正向搜索字符串
	comma := strings.Index(tracer, ",")
	fmt.Println(",所在的位置:", comma) // ,所在的位置: 12
	fmt.Println(tracer[comma+1:]) // 张三bye bye

	add := strings.Index(tracer, "+")
	fmt.Println("+所在的位置:", add) // +所在的位置: -1

	pos := strings.Index(tracer[comma:], "张三")
	fmt.Println("张三,所在的位置", pos) // 张三,所在的位置 1

	fmt.Println(comma, pos, tracer[5+pos:]) // 12 1 来了,张三bye bye

5.1.5 修改字符串

Golang语言的字符串是不可变的

修改字符串时,可以将字符串转换为[]byte进行修改

[]byte和string可以通过强制类型转换

将8080改为8081

	s1 := "localhost:8080"
	fmt.Println(s1)
	// 强制类型转换 string to byte
	strByte := []byte(s1) // localhost:8080

	// 下标修改
	strByte[len(s1)-1] = '1'
	fmt.Println(strByte) // [108 111 99 97 108 104 111 115 116 58 56 48 56 49]

	// 强制类型转换 []byte to string
	s2 := string(strByte)
	fmt.Println(s2) // localhost:8081

6. 类型转换

一个类型的值可以被转换成另一种类型的值。由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明:

//类型 B 的值 = 类型 B(类型 A 的值)

valueOfTypeB = type B(valueOfTypeA)

	a := 5.0
	b := int(a)
	fmt.Printf("%v,%T\n", a, a) // 5,float64
	fmt.Printf("%v,%T", b, b)   // 5,int

类型转换只能在定义正确的情况下转换成功,例如从一个取值范围较小的类型转换到一个取值范围较大的类型(将 int16 转换为 int32)

当从一个取值范围较大的类型转换到取值范围较小的类型时(将 int32 转换为 int16 或将 float32 转换为 int),会发生精度丢失的情况。

License:  CC BY 4.0 test