flora222

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

由上述可见,动态数组声明只需要空的中括号加上基本数据类型,且传参方式为引用传递,修改数据方便,不同长度的切片共用同一个切片形参也没问题

posted on 2026-07-09 00:22  Flora2  阅读(3)  评论(0)    收藏  举报

导航