Golang开发_复合类型


slicemap 在另一篇文章中填坑。

02_Golang开发_复合类型

  • slicemap 在另一篇文章中填坑。

分类

指针

  • 指针是一个代表着某个内存地址的值。
  • 这个内存地址往往是在内存中存储的另一个变量的值的起始位置。
  • Go 语言对指针的支持介于 Java 语言和 C/C++语言之间,它既没有想 Java 语言那样取消了代码对指针的直接操作的能力,也避免了 C/C++语言中由于对指针的滥用而造成的安全和可靠性问题。

基本操作

  • Go 语言虽然保留了指针,但与其它编程语言不同的是:
  • 默认值 nil,没有 NULL 常量
  • 操作符 "&" 取变量地址, "*" 通过指针访问目标对象
  • 不支持指针运算,不支持 "->" 运算符,直接⽤ "." 访问目标成员
package main

import "fmt"

func main() {
    var a int = 10              //声明一个变量,同时初始化
    fmt.Printf("&a = %p\n", &a) //操作符 "&" 取变量地址

    var p *int = nil //声明一个变量 p, 类型为 *int, 指针类型
    p = &a
    fmt.Println("p=", p)
    fmt.Printf("a = %d, *p = %d\n", a, *p)

    *p = 111 //*p 操作指针所指向的内存,即为 a
    fmt.Printf("a = %d, *p = %d\n", a, *p)
}

//运行结果:
//&a = 0xc00001c098
//p= 0xc00001c098
//a = 10, *p = 10
//a = 111, *p = 111 

new函数

  • 表达式 new(T)创建一个 T 类型的匿名变量,所做的是为 T 类型的新值分配并清零一块内存空间,然后将这块内存空间的地址作为结果返回,而这个结果就是指向这个新的 T 类型 值的指针值,返回的指针类型为*T
  • 我们只需使用 new() 函数,无需担心其内存的生命周期或怎样将其删除,因为 Go 语言的内存管理系统会帮我们打理一切。
package main

import "fmt"

func main() {
    var p1 *int
    p1 = new(int)              //p1 为*int 类型, 指向匿名的 int 变量
    fmt.Println("*p1 = ", *p1) //*p1 = 0

    p2 := new(int) //p2 为*int 类型, 指向匿名的 int 变量
    *p2 = 111
    fmt.Println("*p2 = ", *p2) //*p1 = 111
}

指针做函数参数

package main

import "fmt"

func swap01(a, b int) {
    a, b = b, a
    fmt.Printf("swap01 a = %d, b = %d\n", a, b)
}

func swap02(x, y *int) {
    *x, *y = *y, *x
}

func main() {
    a := 10
    b := 20
    
    swap01(a, b) //值传递
    //值传递a = 10, b = 20
    fmt.Printf("值传递a = %d, b = %d\n", a, b)

    swap02(&a, &b) //变量地址传递
    //变量地址传递a = 20, b = 10
    fmt.Printf("变量地址传递a = %d, b = %d\n", a, b)
}

数组

概述

  • 数组是指一系列同一类型数据的集合。
  • 数组中包含的每个数据被称为数组元素(element), 一个数组包含的元素个数被称为数组的长度。
  • 数组⻓度必须是常量,且是类型的组成部分。
package main

func main() {
    var n int = 10
    var a [n]int //err, non-constant array bound n

    var b [10]int //ok
}

操作数组

  • 数组的每个元素可以通过索引下标来访问,索引下标的范围是从 0 开始到数组长度减 1 的位置
package main

import "fmt"

func main() {
    //数组的每个元素可以通过索引下标来访问,索引下标的范围是从 0 开始到数组长度减 1 的位置。
    var a [10]int
    for i := 0; i < 10; i++ {
        a[i] = i + 1
        fmt.Printf("a[%d] = %d\n", i, a[i])
    }

    fmt.Println("----------------------")

    //range 具有两个返回值,第一个返回值是元素的数组下标,第二个返回值是元素的值
    for i, v := range a {
        fmt.Println("a[", i, "]=", v)
    }
}

//a[0] = 1
//a[1] = 2
//a[2] = 3
//a[3] = 4
//a[4] = 5
//a[5] = 6
//a[6] = 7
//a[7] = 8
//a[8] = 9
//a[9] = 10
//----------------------
//a[ 0 ]= 1
//a[ 1 ]= 2
//a[ 2 ]= 3
//a[ 3 ]= 4
//a[ 4 ]= 5
//a[ 5 ]= 6
//a[ 6 ]= 7
//a[ 7 ]= 8
//a[ 8 ]= 9
//a[ 9 ]= 10

内置函数 len(长度) 和 cap(容量) 都返回数组⻓度 (元素数量)

func main() {
    a := [10]int{}
    fmt.Println(len(a), cap(a)) //10 10
}

初始化

func main() {
    //初始化
    a := [3]int{1, 2}           // 未初始化元素值为 0
    b := [...]int{1, 3, 2}      // 通过初始化值确定数组长度
    c := [5]int{2: 100, 4: 200} // 通过索引号初始化元素,未初始化元素值为 0
    fmt.Println(a, b, c)        //[1 2 0] [1 2 3] [0 0 100 0 200]

    //支持多维数组
    d := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
    e := [...][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}} //第二维不能写"..."
    f := [4][2]int{1: {20, 21}, 3: {40, 41}}
    g := [4][2]int{1: {0: 20}, 3: {1: 41}}
    fmt.Println(d, e, f, g)
}

相同类型的数组之间可以使用 == 或 != 进行比较,但不可以使用 < 或 >,也可以相互赋值

func main() {
    //#### 相同类型的数组之间可以使用 == 或 != 进行比较,但不可以使用 < 或 >,也可以相互赋值
    a := [3]int{1, 2, 3}
    b := [3]int{1, 2, 3}
    c := [3]int{1, 2}
    fmt.Println(a == b, b == c) //true false

    var d [3]int
    d = a
    fmt.Println(d) //[1 2 3]
}

在函数间传递数组

  • 根据内存和性能来看,在函数间传递数组是一个开销很大的操作。
  • 在函数之间传递变量时, 总是以值的方式传递的。
  • 如果这个变量是一个数组,意味着整个数组,不管有多长,都会完整复制,并传递给函数。
package main

import "fmt"

func modify(array [5]int) {
    array[0] = 10
    //In modify(), array values: [10 2 3 4 5]
    fmt.Println("In modify(), array values:", array)
}

func main() {
    // 定义并初始化一个数组
    array := [5]int{1, 2, 3, 4, 5}
    modify(array) // 传递给一个函数,并试图在函数体内修改这个数组内容
    //In main(), array values: [1 2 3 4 5]
    fmt.Println("In main(), array values:", array)
}

数组指针做函数参数

// 数组指针做函数参数
func modify(array *[5]int) {
    (*array)[0] = 10
    //In modify(), array values: [10 2 3 4 5]
    fmt.Println("In modify(), array values:", *array)
}

func main() {
    array := [5]int{1, 2, 3, 4, 5} // 定义并初始化一个数组
    modify(&array)                 // 数组指针
    //In main(), array values: [10 2 3 4 5]
    fmt.Println("In main(), array values:", array)
}

数组切片(slice) & map

声明:三二一的一的二|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Golang开发_复合类型


三二一的一的二