GoLangStudy:day3
Go day3
golang语法注意点(指针与数组)
1.Golang指针概念
其实跟c语言和c++是一样的。。。这里简单看一下写法好了
package main
import "fmt"
//定义整型指针p
func changeValue(p *int) {
*p = 100
}
func main() {
var a int = 10
//取变量a的地址进行传参
changeValue(&a)
fmt.Println("a = ", a)
}
//输出:a=100
经典指针使用场景:交换两个数字的值
package main
import "fmt"
func changeValue(p1 *int, p2 *int) {
var temp int = 0
temp = *p1
*p1 = *p2
*p2 = temp
}
func main() {
var a int = 10
var b int = 34
changeValue(&a, &b)
fmt.Println("a = ", a)
fmt.Println("b = ", b)
}
输出结果:
a = 34
b = 10
2.defer语句调用顺序
defer关键字修饰的表达式会在defer所在函数体运行结束之前调用,可以参照c++中的析构语句来进行理解
知识点1:defer调用顺序与写入顺序相反(入栈与出栈)
一个函数体中可以有多个defer,并且调用顺序与写入顺序相反(与c++中构造对象与析构对象的顺序相同)
示例:
package main
import "fmt"
func main() {
//顺序写入defer,理论上先输出end2
defer fmt.Println("main end1")
defer fmt.Println("main end2")
fmt.Println("main:: print1")
fmt.Println("main:: print2")
}
输出结果:
main:: print1
main:: print2
main end2
main end1
//与预期输出一致
知识点2:defer与return的调用顺序:先return后defer
若一个函数体中同时存在return语句和defer语句,那么会先执行return语句,最后执行defer语句
示例:
package main
import "fmt"
func deferFunc() int {
fmt.Println("defer func exe")
return 0
}
func returnFunc() int {
fmt.Println("return func exe")
return 0
}
func deferandreturn() int {
defer deferFunc()
return returnFunc()
}
func main() {
deferandreturn()
}
输出结果:
return func exe
defer func exe
可见return语句先于defer语句执行
不难理解,因为return是函数体的一部分,等到函数体执行完毕最后才调用defer语句,所以最后执行defer
3.golang中的数组与动态数组
知识点1:声明固定长度数组以及查看数据类型
package main
import "fmt"
func main() {
// 声明固定长度数组以及遍历输出
var myArray1 [10]int
for i := 0; i < len(myArray1); i++ {
fmt.Println(myArray1[i])
}
//声明固定长度数组,并赋初始值
myArray2 := [8]int{1, 2, 3, 4}
//range是go语言的一个关键字,作用为遍历容器,且固定双返回值
//index:数组下标 value:下标对应数组元素的值
for index, value := range myArray2 {
fmt.Println("index = ", index, "value = ", value)
}
//查看数组的数据类型(不同长度的数组数据类型不同)
fmt.Printf("type of MyArray1: %T\n", myArray1)
fmt.Printf("type of MyArray2: %T\n", myArray2)
}
输出结果:
0
0
0
0
0
0
0
0
0
0
index = 0 value = 1
index = 1 value = 2
index = 2 value = 3
index = 3 value = 4
index = 4 value = 0
index = 5 value = 0
index = 6 value = 0
index = 7 value = 0
type of MyArray1: [10]int
type of MyArray2: [8]int
由type of MyArray1: [10]int,type of MyArray2: [8]int两行可见,数组的数据类型不只有int等基本类型,还与数组长度有关
那么我们如果要将数组进行传参,该如何写呢?
func arrayTest(array [8]int) {
fmt.Println("base array test")
}
func main(){
//只能传类型为[4]int的myArray2
arrayTest(myArray2)
}
如上面代码所示,固定长度数组要传参,只能传对应长度的数组,比如[8]int类型的形参,传入[10]int类型的数组会报错
并且这也只是一个值传递,要对数组内容进行修改十分麻烦
有没有什么办法能够解决这个问题呢?
知识点2:动态数组,切片(slice)
package main
import "fmt"
func printArray(array []int) {
//不需要双返回值的其中一个值时,可以使用下划线匿名代替
for _, value := range array {
fmt.Println("value:", value)
}
//slice切片为引用传递,不需要使用指针等工具,可直接修改原数组
array[0] = 9
}
func main() {
//动态数组(slice),声明方式示例:[]int{}
myArray := []int{1, 2, 3, 4, 5}
fmt.Printf("type of myArray:%T\n", myArray)
printArray(myArray)
fmt.Println("----------")
//输出被修改后的数组
for _, value := range myArray {
fmt.Println("value:", value)
}
}
输出结果:
type of myArray:[]int
value: 1
value: 2
value: 3
value: 4
value: 5
----------
value: 9
value: 2
value: 3
value: 4
value: 5
由上述可见,动态数组声明只需要空的中括号加上基本数据类型,且传参方式为引用传递,修改数据方便,不同长度的切片共用同一个切片形参也没问题
浙公网安备 33010602011771号