Image Description

在 Go语言中,数据类型用于声明函数和变量。

数据类型的作用是按所需内存大小的不同把数据分类,提高内存的使用效率。Go语言主要有以下几种数据类型:

一、布尔类型 (bool)

值:true 和 false,默认值为 false

package main

import "fmt"

func main() {
    var v1, v2 bool         
    v1 = true
    v3, v4 := false, true
    fmt.Print("v1:", v1)  
    fmt.Print("\nv2:", v2)
    fmt.Print("\nv3:", v3)
    fmt.Print("\nv4:", v4)
}

二、数字类型

整型 int 和浮点型 float32、float64,Go 语言支持整型和浮点型数字,并且支持复数,其中位的运算采用补码。

package main

import "fmt"

func main() {
    //无符号整形,默认值都是0
    var u8 uint8
    var u16 uint16
    var u32 uint32
    var u64 uint64
  
    u8 = 255
    u16 = 65535
    u32 = 4294967295
    u64 = 18446744073709551615

    //整型
    var i8 int8
    var i16 int16
    var i32 int32
    var i64 int64

    i8 = 127
    i16 = 32767
    i32 = 2147483647
    i64 = 9223372036854775807

    var i int
    i = -9223372036854775808

    var f32 float32
    var f64 float64

    f32 = 1.12345678
    f64 = 1.12345678901234567

    var c64 complex64  //复数型
    var c128 complex128

    c64 = 1.12345678 + 1.12345678i
    c128 = 2.1234567890123456 + 2.1234567890123456i

    var b byte  //字符型      
    var r1, r2 rune
    fmt.Printf("b: %v, r1: %v, r2: %v\n", b, r1, r2)

    b = 'a'
    r1 = 'b'
    r2 = '字'
    fmt.Printf("b: %v, r1: %v, r2: %v\n", b, r1, r2)

    b = u8
    r1 = i32
    fmt.Printf("b: %v, r1: %v\n", b, r1) 

    //指针地址
    var p uintptr
    p = 18446744073709551615
    fmt.Printf("p: %v\n", p)
}

三、字符串 (string)

Go 语言默认编码都是 UTF-8

package main

import "fmt"

func main() {
    var str1 string
    str1 = `hello world`
    str2 := "你好世界"
    
    str := str1 + " " + str2
    fmt.Println(str1)
    fmt.Println(str2)
    fmt.Println(str)

    l := len(str)
    //遍历字符串
    for i := 0; i < l; i++ {
        chr := str[i]
        fmt.Println(i, chr)
    }
}

四、指针(pointer)

指针其实就是指向一个对象的地址值(对象指任何一种类型数据、包括指针本身),对指针的操作都会映射到指针所指的对象上。

package main

import (
    "fmt"
)

func main() {
    
    var p *int 
    //定义指向int型的指针 默认值为空nil
    //nil指针不指向任何有效存储地址,操作系统默认不能访问
    //fmt.Printf("%x\n", *p) // 编译报错
    
    var a int = 10
    p = &a            // 取地址
    add := a + *p     // 取值

    fmt.Println(a)    // 输出:10
    fmt.Println(p)    // 输出:0xc0420080b8
    fmt.Println(add)  // 输出:20
}

五、数组(array)

数组是一组相同数据类型数据的集合,数组定义后大小固定,不能更改。每个元素称为element,声明的数组元素的默认值都是对应类型的 0 值。

数组在 Go语言中是一个值类型(value type),所有值类型变量在赋值和作为参数传递时都会产生一次复制动作,即对原值的拷贝。

package main

import "fmt"

func main() {

    var arr [2]int
    fmt.Println(arr)  //输出[0 0]
    arr[0] = 1
    arr[1] = 2
    fmt.Println(arr)  //输出[1 2]

    //声明并赋值
    var intArr = [2]int{1, 2}
    strArr := [3]string{`aa`, `bb`, `cc`}
    fmt.Println(intArr)
    fmt.Println(strArr)

    //声明时不指定数组大小,赋值后自动计算
    var arr1 = [...]int{1, 2}
    arr2 := [...]int{1, 2, 3}
    fmt.Println(arr1) //输出[1 2]
    fmt.Println(arr2) //输出[1 2 3]

    //声明时不设定大小,赋值时指定索引
    var arr3 = [...]int{1: 22, 0: 11, 2: 33}
    arr4 := [...]string{2: "cc", 1: "bb", 0: "aa"}
    fmt.Println(arr3) //输出:[11 22 33]
    fmt.Println(arr4) //输出:[aa bb cc]

    //遍历数组
    for i := 0; i < len(arr4); i++ {
      v := arr4[i]
      fmt.Printf("i:%d, value:%s\n", i, v)
    }
}

六、切片(slice)

因为数组的长度定义后不可修改,所以需要切片来处理可变长度数组。

切片可以看作是一个可变长的数组,是一个引用类型。它包含三个数据:

1.指向原生数组的指针

2.切片中的元素个数

3.切片已分配的存储空间大小

声明一个切片,或从数组中取一段作为切片数据:

package main

import "fmt"

func main() {

    var sl []int              //声明一个切片
    sl = append(sl, 1, 2, 3)  //往切片中追加值
    fmt.Println(sl)           //输出:[1 2 3]

    var arr = [5]int{1, 2, 3, 4, 5} //初始化一个数组
    var sl1 = arr[0:2]              //冒号:左边为起始位 右边为结束位
    var sl2 = arr[3:]
    var sl3 = arr[:5]

    fmt.Println(sl1) //输出:[1 2]
    fmt.Println(sl2) //输出:[4 5]
    fmt.Println(sl3) //输出:[1 2 3 4 5]

    sl1 = append(sl1, 11, 22)  // 追加元素
    fmt.Println(sl1)           // 输出:[1 2 11 22]
}

使用 make 直接创建切片,语法:make([]类型, 大小,预留空间大小),make() 函数用于声明slice切片、map字典、channel通道。

package main

import "fmt"

func main() {

    var sl1 = make([]int, 5)
    sl2 := make([]int, 5, 10)
    sl3 := []string{`aa`, `bb`, `cc`}
    
    fmt.Println(sl1, len(sl1))
    fmt.Println(sl2, len(sl2))
    fmt.Println(sl3, len(sl3))

    sl1[1] = 1
    sl1[4] = 4
    //sl1[5] = 5    //编译报错,超出定义大小

    sl1 = append(sl1, 5)
    fmt.Println(sl1, len(sl1))

    sl2[1] = 1
    sl2 = append(sl2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
    fmt.Println(sl2, len(sl2))

    //遍历切片
    for i := 0; i < len(sl2); i++ {
      v := sl2[i]
      fmt.Printf("i: %d, value:%d \n", i, v)
    }
}