Skip to content

数据类型 ​


Go 是一种强类型语言。
每个变量都绑定到特定的数据类型,并且只接受与此类型匹配的值。

数据类型 ​

类型
基本类型数字、字符串和布尔值
聚合类型数组和结构
引用类型指针、切片、哈希、函数和管道
接口类型接口

数值类型 ​

基本类型 ​

类型说明(位是bit)
int有符号整数,为32位或64位,由编译器决定
uint无符号整数,为32位或64位,由编译器决定
int88位有符号整数
int1616位有符号整数
int3232位有符号整数
int6464位有符号整数
uint88位无符号整数
uint1616位无符号整数
uint3232位无符号整数
uint6464位无符号整数
runeint32 数据类型的别名。 它用于表示 Unicode 字符(或 Unicode 码位)
uintptr无符号int指针类型
float32浮点数
float64浮点数
complex128复数
complex64复数
bool布尔类型
byte字节类型,同uint8
string字符串类型
error错误类型

bool类型 ​

布尔类型值为true和false
不支持自动或者强制类型转换

类型转换 ​

不同类型之间不支持运算
显式声明类型转换

go
var test int32 = 1
var test2 uint32 = (uint32)test

类型声明 ​

type new_type old_type

go
type INT int

new_type和old_type 底层相同,但仍是不同的类型

字符类型 ​

byte: 代表UTF8字符串的单个字节的值
rune: 代表unicode字符

指针 ​

指针的值是一个变量的地址

变量生命周期 ​

go
var p *int
fun f() {
    var x int = 1
    p = &x
}
//由于p指向局部变量x,x将从堆申请内存

fun g() {
    y := new(int)
    *y = 1
}
//由于y指向的地址只在函数内使用,当函数结束时,该内存将被自动释放

字符串 ​

字符串是不可变的字节序列,初始化后不能被修改
文本字符串被解读成安UTF-8编码的Unicode字符
每个元素为uint8类型

go
package main
import "fmt"

func main() {
    test := "123"
    test1 := "测试"
    fmt.Println(len(test), len(test1))

    test2 := test[:1] //创建新的字符串
    test3 := test + test1 //字符串拼接,产生新的字符串
}
//每个汉字占3个字节
//输出: 3 6

扩容 ​

定义新的字符串

遍历 ​

go
var str = "it is test"

//根据长度遍历
strLen := len(str)
for i:=0; i<strLen; i++ {
    fmt.PrintLn(str[i])
}

//range
for i,v := range str { //注意range返回值为int32类型
    fmt.PrintLn(i,v)
}

处理包 ​

  • bytes
  • strings
  • strconv
  • unicode

数组 ​

数组是一种特定类型且长度固定的数据结构

  • 可以有零个或多个元素
  • 必须在声明或初始化时指定大小
  • 无法动态调整大小
  • 通过下标访问,从0开始到len-1
  • 根据类型默认初始化,或者指定赋值

鉴于这些原因,数组在 Go 程序中并不常用,但它们是切片和映射的基础。

声明 ​

go
//int类型数组,该数组有3个元素
var a [3]int
//string类型数组,该数组有3个元素
var b [3]string
//初始化多维数组
var twoD [3][5]int

初始化 ​

go
//申请全局变量
var cities [5]string = [5]string{"New York", "Paris", "Berlin", "Madrid"}

//函数内局部变量
cities := [5]string{"New York", "Paris", "Berlin", "Madrid"}

//如果不知道需要多少个位置,但知道具有多少数据,那么使用省略号 (...),如下例所示:
q := [...]int{1, 2, 3}
//注意:=只能在函数内使用

//特定位置赋初值
numbers := [...]int{99: -1}

值类型 ​

数组是值类型,在赋值或作为参数传递时,将被复制

切片 ​

var name []Type
切片只是基础数组的一个视图
切片的大小是动态的,不是固定的

属性 ​

  • 指针,指向原生数组的指针
  • 长度,切片内元素的个数。使用len()计算当前切片长度
  • 容量,切片存储空间大小。使用cap()计算容量。
  • 无法动态扩容,只能创建新切片(append时会自动扩容)

空切片 ​

通过len判断数组是否为空

go
var s []int     //len(s)==0 s==nil
s = nil         //len(s)==0 s==nil
s = []int(nil)  //len(s)==0 s==nil
s = []int{}     //len(s)==0 s!=nil

创建 ​

  • 基于数组创建切片
  • 基于切片创建切片
  • 使用make()创建
go
//该切片的长度len和cap均为0
var slice0 []string 

//基于数组创建切片 len:2 cap:12
months := [...]string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
slice1 := months[0:1] 

//使用make创建切片,len:10 
slice2 := make([]string, 10, 100) cap:100

访问 ​

切片运算符 s[i]

追加元素 ​

内置函数 slice = append(slice, element)向切片添加元素
当切片长度不够时,会自动分配新的切片

删除 ​

无内置删除函数
通过创建新切片删除

go
 letters := []string{"A", "B", "C", "D", "E"}
 remove := 2
 letters = append(letters[:remove], letters[remove+1:]...)

切片拷贝 ​

copy(dst, src []Type)

map ​

哈希表

格式 ​

go
var hmap map[key]value

初始化 ​

Go
    studentsAge := map[string]int{
        "john": 32,
        "bob":  31,
    }

    t := map[int]int{} //创建空map

    var studentsAge = make(map[string]int)
    
    //注意
    var studentsAge map[string]int
    //该方式定了一个nil,不能直接访问

添加 ​

Go
    studentsAge := make(map[string]int) //正确定义
  射,后续赋值将出错
    studentsAge["john"] = 32
    studentsAge["bob"] = 31
    fmt.Println(studentsAge)

查找 ​

go
value, ok := map_test["123"]
if ok {
    do something...
}

访问项 ​

下标表示法 map[key]

Go
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31
fmt.Println("Bob's age is", studentsAge["bob"])
}

###遍历

Go
studentsAge := make(map[string]int)
studentsAge["john"] = 32
studentsAge["bob"] = 31

for name, age := range studentsAge {
    fmt.Printf("%s\t%d\n", name, age)
}

删除 ​

内置函数delete()删除

Go
    studentsAge := make(map[string]int)
    studentsAge["john"] = 32
    studentsAge["bob"] = 31
    delete(studentsAge, "john")
    fmt.Println(studentsAge)
}

结构体 ​

结构体可包含零个或多个任意类型的字段,并将它们表示为单个实体。

声明和初始化 ​

使用 struct 关键字声明结构

Go
// 例如,若要定义员工结构
type Employee struct {
    ID        int
    FirstName string
    LastName  string
    Address   string
}

//然使用新类型声明一个变量
var john Employee
//声明变量的同时对其进行初始化
employee := Employee{1001, "John", "Doe", "Doe's Street"}
//指定字段赋值
employee := Employee{LastName: "Doe", FirstName: "John"}

//通过.访问
employee.ID = 1001
fmt.Println(employee.FirstName)

成员定义 ​

通常将结构体成员首字母大写
便于夸包引用

结构嵌入 ​

通过 Go 中的结构,可将某结构嵌入到另一结构中

Go
//一种针对员工,一种针对合同工   
//你可具有一个包含公共字段的 Person 结构,如下例所示:
//公共字段
type Person struct {
    ID        int
    FirstName string
    LastName  string
    Address   string
}
//Employee
type Employee struct {
    Information Person
    ManagerID   int
}

匿名嵌套 ​

定义只包含类型,不带名称的结构体成员

go
type Person struct {
    ID        int
    FirstName string
    LastName  string
    Address   string
}
//Contractor
type Employee struct {
    Person  //匿名嵌套
    ManagerID int
}
Go
package main
import "fmt"

type Person struct {
    ID        int
    FirstName string
    LastName  string
    Address   string
}

type Employee struct {
    Person
    ManagerID int
}

type Contractor struct {
    Person
    CompanyID int
}

func main() {
    employee := Employee{
        Person: Person{
            FirstName: "John",
        },
    }
    employee.LastName = "Doe"
    fmt.Println(employee.FirstName)
}