当我在指针变量上使用不同的赋值运算符时,程序的行为会有所不同。

huangapple go评论72阅读模式
英文:

Program behaves differently when I use a different assignment operator on a pointer variable

问题

我在玩耍时遇到了这种奇怪的行为:

package main

import "fmt"

var appConfig *map[string]interface{}

func main() {
	// 正常工作
	//appConfig = &map[string]interface{}{
	//	"name": "marcus",
	//}
	// 导致恐慌:运行时错误:无效的内存地址或空指针解引用
	appConfig := &map[string]interface{}{
		"name": "marcus",
	}
	fmt.Println("Config:", *appConfig)
	getName()
}

func getName() {
	fmt.Println("Name is ", (*appConfig)["name"])
}

我不明白为什么如果我使用短变量声明 := 而不是普通的 = 赋值运算符,程序会崩溃。有人能给我解释一下这种行为差异的原因吗?提前谢谢。

英文:

I was playing around when I encountered this strange behavior:

package main

import "fmt"

var appConfig *map[string]interface{}

func main() {
	// Works fine
	//appConfig = &map[string]interface{}{
	//	"name": "marcus",
	//}
	// Causes panic: runtime error: invalid memory address or nil pointer dereference
	appConfig := &map[string]interface{}{
		"name": "marcus",
	}
	fmt.Println("Config:", *appConfig)
	getName()
}

func getName() {
	fmt.Println("Name is ", (*appConfig)["name"])
}

I don't understand why would the program crash if I use the short variable declaration := instead of the plain = assignment operator. Could someone enlighten me as to the reason behind the difference in behaviours? Thanks in advance.

答案1

得分: 5

你面临的问题是由于变量遮蔽引起的。在你的第二个示例中,当你使用短变量声明(:=)时,在 main 函数的作用域内创建了一个名为 appConfig 的新局部变量,它与你在代码开头声明的全局 appConfig 变量是不同的。

当你使用普通赋值操作符(=)时,你将一个指向 map 的指针赋给了全局 appConfig 变量。这意味着当你调用 getName() 时,它可以访问全局 appConfig 变量并获取正确的值。

然而,当你使用短变量声明(:=)时,在 main 函数的作用域内创建了一个新的局部 appConfig 变量,而全局 appConfig 变量保持未初始化(nil)。当你调用 getName() 时,它尝试访问全局 appConfig 变量,而该变量仍然为 nil,导致发生 panic。

简而言之: 你需要使用普通赋值操作符(=)来确保将值赋给全局 appConfig 变量。

英文:

The problem you are facing is due to variable shadowing. In your second example, when you use the short variable declaration (:=), you create a new local variable named appConfig within the main function's scope, which is different from the global appConfig variable you declared at the beginning of your code.

When you use the plain assignment operator (=), you assign a pointer to a map to the global appConfig variable. This means that when you call getName(), it can access the global appConfig variable and get the correct value.

However, when you use the short variable declaration (:=), you create a new local appConfig variable within the scope of the main function, and the global appConfig variable remains uninitialized (nil). When you call getName(), it tries to access the global appConfig variable, which is still nil, resulting in a panic.

TL;DR: You need to use the plain assignment operator (=) to ensure you're assigning the value to the global appConfig variable.

huangapple
  • 本文由 发表于 2023年4月6日 17:41:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75948049.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定