Golang基础语法与特性(三) | 青训营笔记

100 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第3天

1.Go的基础语法(续)

(1). Go的指针

Golang是基于C++的,也有类似于C++的指针机制,有了指针可以非常方便的对变量进行操作。
首先Golang中的地址也是通过取地址符&得到的:

var x int = 1 
fmt.Printf("Address: %x\n", &x)

指针的定义和赋值也类似,其中,输出xPoint存储的地址得到x的地址,输出*xPoint得到x的值:

var int x = 10
var xPoint *int
xPoint = &x 

Golang的空指针类似于NULL、nullptr、null,为nil,若要判空 xPoint != nil 即可。
指向指针的指针可以类似于以下定义,可以顺次指针的指针的指针等操作:

var xPointP **int //该指针存储某个指针的地址

前面总结过,swap函数的引用传递中,函数的形参实际上是指针参数,接受实参地址。

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

指针应用到数组上,需要依次赋值:

var point [N]*int;
num := []int{1,2,3}
for i := 0; i < N; i++ {
    point[i] = &num[i]
}
(2). Go的数组

数组是数据结构中顺序表的物理实现,和其他高级语言类似,Golang中的数组也具有类似的性质和语法。
数组声明后初始化方式有很多种,一维数组的相关内容如下代码所示:

/* 一维数组声明 */
var num1 [20] int
/* 一维数组初始化 */
var num2 = [5]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //普通初始化 不可以var 
num3 := [5]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //快速初始化
var num4 = [...]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //不定长普通初始化
num5 := [...]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //不定长快速初始化
num6 := [5]float64{1:3.14, 4:2.71828} //指定位置初始化,相当于num6[1], num6[4] = 3.14, 2.71828

对于二维数组,相关内容如下。
二维数组的声明方式:

var num1 [3][4] int

二维数组的初始化方式:

/* 二维数组初始化 */
num2 := [][]int{} //一个空二维数组

num3 := [3][2]int{  
 {0, 1},
 {2, 3},
 {4, 5},  //逗号不可省略
}
num4 := [3][2]int{  
 {0, 1},
 {2, 3},
 {4, 5}) //没有逗号
 
num5 := [...][]int{
    {1, 2, 3, 4},
    {10, 20, 30, 40}, //使用...不定长行数
}

二维数组的赋值方式:

num6 := [][]int{}
r1 := []int{1, 2}
r2 := []int{3, 4}
num6 = append(num6, r1)
num6 = append(num6, r2) //num5为一个2行2列的二维数组

s := [2][2]string{}
s[0][0] = "aa"
s[0][1] = "bb"
s[1][0] = "cc"
s[1][1] = "dd" //依次赋值,可以用循环输入方式

二维数组的遍历方式:

//使用range
for i := range num {
    for j := range num[i] {
        fmt.Println(num[i][j])
    }
}
//使用普通for循环
for i:=0 ; i<n; i++ {
    for j:=0 ; j<m; j++ {
        fmt.Println(num[i][j])
    }
}

对于多维数组,其语法和操作类似于二维数组。
对于不定维数组,可以通过append函数依次添加元素数量不同的一维数组达到效果。

数组在函数参数传递上的状况,大致分为三种,数组参数、指针参数、切片参数: 数组作为函数参数时,为值传递,不会改变数组的值:

func change1(nums [3]int) {    
    nums[0] = 2
}

指针参数,引用传递,会改变值:

func change2(nums *[3]int) {    
    nums[0] = 2
}

Go 语言中对数组的处理,一般采用切片,切片包含对底层数组内容的引用,作为函数参数时,类似上面那种指针传递,会修改值,这种参数只能用于切片([]内没有数字的数组):

func change3(nums []int) {    
    nums[0] = 2
}

这种切片不会改变值,因为a长度已经改变,之后的操作都不起作用:

func change4(nums []int) {
    nums = append(nums, 1, 2, 3, 4)
    nums[0] = 10
}

这样result的值才能是真正修改的结果:

result := [][]int{}
func change5(a []int){
    a = append(a, 1, 2, 3, 4)
    a[0] = 10
    temp := make([]int, len(a))
    copy(temp, a)
    result = append(result,temp) 
}
func main() {    
    var nums1 = [3]int{1, 2, 3}   
    var nums2 = []int{1, 2, 3}    
    change1(nums1)    
    fmt.Println(nums1)  //[1 2 3]     
    change2(&nums1)    
    fmt.Println(nums1)  //[2 2 3]    
    change3(nums2)    
    fmt.Println(nums2)  //[2 2 3]
    change4(nums2)    
    fmt.Println(nums2)  //[2 2 3]
    change5(nums2)    
    fmt.Println(result)  //[10 2 1 2 3 4]
}
(3). Go的算法竞赛数据输入

值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。

(4). Go的结构体

值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。

(5). Go的切片

值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。

(6). Go的范围

值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。

(7). Go的集合

值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。

(8). Go的接口

值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。