第6节 Go的数据类型

201 阅读5分钟

1. 数据类型分类

image.png

1.1 按值类型和引用类型划分

  • 值类型:基本数据类型 int 系列、float 系列、bool、string、数组 和 结构体 struct
  • 引用类型:指针、切片、map、管道、interface 等引用类型

2. 整数类型

主要用于存放整数值,比如 1、2、3、-1、8000 等

2.1 无符号整数类型

类型有无符号占用存储空间范围默认值
uint32位系统4字节
64位系统8字节
0 ~ 232 2^{32} - 1
0 ~ 26412^{64} - 1
0
uint81字节0 ~ 2550
byte1字节,等价于 uint80 ~ 2550
uint162字节0 ~ 216 2^{16} - 10
uint324字节0 ~ 232 2^{32} - 10
uint648字节0 ~ 26412^{64} - 10

2.2 有符号整数类型

类型有无符号占用存储空间范围默认值
int32位系统4字节
64位系统8字节
-231 2^{31} ~ 231 2^{31} - 1
-263 2^{63} ~ 263 2^{63} - 1
0
int81字节-128 ~ 1270
int162字节-215 2^{15} ~ 215 2^{15} - 10
int324字节-231 2^{31} ~ 231 2^{31} - 10
rune4字节,等价于 int32
表示一个 Unicode 码
-231 2^{31} ~ 231 2^{31} - 10
int648字节-263 2^{63} ~ 263 2^{63} - 10

2.2.1 什么是有符号和无符号?

  • 有符号数可以表示特定类型规定范围内的整数(包括负数),而无符号数只能表示非负数(0及正数)
通过高位的 0 表示正数,1 表示负数 
(1) 无符号数: 1 1 1 1 1 1 1 1  表示十进制的 255
    0 ~ 255
(2) 有符号数: 0 1 1 1 1 1 1 1  表示十进制的 127 = 2^7 - 1 

3. 浮点类型

浮点数据类型被用于存放小数,它分为单精度和双精度两种类型

类型有无符合占用存储空间范围默认值
单精度 float324字节-3.403E38 ~ 3.403E380
单精度 float324字节-3.403E38 ~ 3.403E380

3.1 浮点数使用细节

  • 浮点数有固定的取值范围和长度,不受操作系统影响
  • 浮点型默认声明成 float64,所以在实际开发中,浮点类型变量尽量声明成 float64
  • 浮点型常量的表示形式
package main

import "fmt"

func main() {
    // 十进制数据的声明方式
    f3 := 5.12
    f4 := 0.123
    f5 := .123
    // f3=5.120000, f4=0.123990, f5=0.123000
    fmt.Printf("f3=%f, f4=%f, f5=%f\n",f3,f4,f5)
    
    // 科学计数法表示
    k1 := 3.125E2
    k2 := 3.125E-2
    // k1=3.125000E+02, k2=3.125000E-02
    fmt.Printf("k1=%E, k2=%E\n",k1,k2)
}
  • 浮点型数据可能存在精度损失,实际开发中需要特别注意
package main

import "fmt"

func main() {
    var k3 float32 = -123.00000901
    var k4 float64 = -123.00000901
    // k3=-123.000008, k4=-123.000009
    fmt.Printf("k3=%f, k4=%f\n",k3,k4)
}

4. 字符类型

Go 中并没有专门用来保存字符的数据类型,如果要保存字符一般使用byteint。通常我们理解的字符串是由多个字符连接在一起的字符序列,但是在 Go 中,字符串是由单个字节连接组成的

package main

import "fmt"

func main() {
	var c1 byte = 'a'
	var c2 byte = '0'
	fmt.Printf("c1=%c, c2=%c\n",c1,c2)

	// 编译报错:cannot use '中' (untyped rune constant 20013) as byte value in variable declaration (overflows)
        // 报错原因:'中' 这个字符的码值大于255
	//var c3 byte ='中'

	var c3 int ='中'
	fmt.Printf("c3=%c\n",c3)
}

代码分析:

4.1 字符类型使用细节

  • 字符常量必须使用单引号括起来var a byte = '1'
  • Go 中允许声明转移字符
package main

import "fmt"

func main() {
    var c5 int = '\n'
    fmt.Printf("c5=%c",c5)
}

image.png

意思是此时的 var c5 int = '\n' 还是表示换行

  • 英文字符在内存中占用1个字节,中文字符在内存中占用3个字节
  • Go 中,字符的本质就是就是一个整数,在 Go 的程序中直接输出该字符时会输出对应的 Unicode 码值
package main

import "fmt"

func main() {
    var c3 int ='中'
    fmt.Printf("c3=%c\n",c3)
    fmt.Println("c3=",c3)
}

image.png

  • 字符类型可以进行四则运算,因为字符本质就是一个整数
package main

import "fmt"

func main() {
    var n1 = 20 + 'a'
    // n1=117
    fmt.Printf("n1=%v\n",n1)
}
  • Go 语言默认统一使用 utf-8 编码,再也不用担心乱码问题

5. 布尔类型

bool 类型只有 true 和 false 两个值,它占用一个字节

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    var b bool = false
    // b=false, 占用字节:1
    fmt.Printf("b=%v, 占用字节:%d\n",b,unsafe.Sizeof(b))
}

6. 字符串类型

Go 中的字符串是由单个字节连接而成的字符序列,Go 中的字符串统一使用 utf-8 编码

package main

import "fmt"

func main() {
	var address string = "北京市朝阳区科创中心101号"
	// address=北京市朝阳区科创中心101号
	fmt.Printf("address=%v\n",address)
}

6.1 字符串使用细节

  • 字符串的默认值是空串 ""
  • Go 中的字符串不可变,即字符串一旦被赋值,字符串就不能被修改
package main

import "fmt"

func main() {
	var address string = "北京市朝阳区科创中心101号"
	// address=北京市朝阳区科创中心101号
	fmt.Printf("address=%v\n",address)

	// 编译报错:cannot assign to address[0] (value of type byte)
	// 意思就是字符串的内容不可改变
	address[0] = "西"
	fmt.Printf("address=%v\n",address)
}
  • 字符串拼接
package main

import "fmt"

func main() {
    var address string = "北京市朝阳区科创中心" + "101号"
    address += "13层"
    fmt.Printf("address=%v\n",address)
}
  • 字符串换行时 + 号必须写在上一行的行行尾,不然编译报错
package main

import "fmt"

func main() {
    // invalid operation: operator + not defined on "from " (untyped string constant)
    // var text string = "I " + "am " 
    //  + "from " + "china"
    // fmt.Println(text)

    var text string = "I " + "am " + 
		      "from " + "china"
    fmt.Println(text)
}
  • 字符串可以使用双引号 "" 和 `` 反引号
package main

import "fmt"

func main() {
    // abcdefg\n1234
    var t string = `abcdefg\n1234`
    fmt.Println(t)
    
    // abcdefg
    // 1234
    var f string = "abcdefg\n1234"
    fmt.Println(f)
}

注意:反引号可以输出原生字符串,包括换行符和特殊字符,可实现防止攻击、源代码输出