Go-知识简短变量声明


githuio地址:https://a18792721831.github.io/

1. 简短变量声明符

在Go语言中,可以使用关键字var或直接使用简短变量声明符:=声明变量。
相比而言,使用:=更多一些,而且使用:=可以自动推断类型,而不需要关注类型问题。
比如:

    a := "string"
    a := 2
    a := struct{}

2. 简短变量赋值可能会重新声明

使用:=可能会重新声明变量,导致出现在不同的作用域中,很可能创建了新的同名变量,导致同一个函数不同作用域的同名变量不符合预期。
多说无益,请看如下代码:

func TestTmpVar(t *testing.T) {
	a := 1
	a++
	fmt.Printf("a=%d\n", a)
	if a > 0 {
		a, err := addNum(a)
		if err != nil {
			fmt.Printf("err=%s", err)
		}
		fmt.Printf("a=%d\n", a)
	}
	fmt.Printf("a=%d\n", a)
}
func addNum(a int) (int, error) {
	return a + 1, nil
}

请想想上述代码输出结果是什么?
在这里插入图片描述

上面的写法非常常见,使用:=调用了一个函数,然后接收函数返回的结果,如果有错误,那么处理错误,没有错误,那么将结果赋值给变量。
但是要非常注意,因为a已经在外部声明了,而方法调用又是在if内部,所以就相当于在if内,创建了一个同名函数,并没有按照我们的预期处理。
如果a是指针,那么,后面在使用a的时候,肯定会出现空指针panic
为什么会出现这样的问题呢?
这是因为:=的规则:

:=左侧存在新变量时(err),已声明的变量(a)会被重新声明,不会有其他额外的副作用。
:=左侧没有新变量是不允许的,编译会提示no new variable on left side of :=

所以如果当一个变量第一次声明和后续全部使用过程中,都在同一个作用域内时,上述使用确不会出现问题,因为作用域相同。
比如上述代码如果去掉if

func TestTmpVar(t *testing.T) {
	a := 1
	a++
	fmt.Printf("a=%d\n", a)
	//if a > 0 {
	a, err := addNum(a)
	if err != nil {
		fmt.Printf("err=%s", err)
	}
	fmt.Printf("a=%d\n", a)
	//}
	fmt.Printf("a=%d\n", a)
}
func addNum(a int) (int, error) {
	return a + 1, nil
}

输出如下
在这里插入图片描述

因为虽然使用:=重新定义了新的变量,但是在后面使用的过程中,使用的也是新的变量。

3. 简短变量赋值不能用于函数外部

简短变量赋值只能用于函数内,不能使用:=来声明和初始化全局变量。
比如:

package study
test := "test"

会出现编译错误,提示为syntax error: non-declaration statement outside function body
可以理解为:=实际上会拆分成两个语句,一个是声明,一个是赋值。而赋值语句不允许出现在函数外部。

4. 简短变量赋值作用域问题

考虑最开始的例子,假设变量时指针类型。

type tes struct {
	a int
	z string
}

func TestTmpStruct(t *testing.T) {
	a := tes{
		a: 1,
		z: "1",
	}
	a.a++
	fmt.Printf("a = %+v, %#p\n", a, &a)
	if a.a > 0 {
		a, err := addNumStruct(a)
		if err != nil {
			fmt.Println(err)
		}
		fmt.Printf("a = %+v, %#p\n", a, &a)
	}
	fmt.Printf("a = %+v, %#p\n", a, &a)
}
func addNumStruct(a tes) (tes, error) {
	a.a++
	return a, nil
}

查看输出,可以很明显的看到创建了新的变量:
在这里插入图片描述

那么新的问题来了,假设不是if,而是for那么:
在这里插入图片描述

可以很明显的看到创建了很多的变量,这些变量属于for作用域内的临时变量,当大量生成临时变量时,
虽然Go不需要我们管理内存,但是会导致程序性能的下降。

5. 总结

简短变量声明操作符:=虽然很好用,但是需要注意:=的特性,在使用的时候,需要避免因为使用:=而导致的同名变量声明,以及作用域内无效变量的声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a18792721831

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值