Golang中如何在函数外部给未初始化的变量赋值

Golang中如何在函数外部给未初始化的变量赋值 我搜索并阅读了所有关于变量的在线博客,查阅了我所有关于Go语言的书籍,奇怪的是这个新手问题在任何地方都没有涉及。

如何在函数外部(即在Go的顶层)为未初始化的变量赋值?只能在初始声明时进行赋值吗?我可以在后续的函数中修改它,但在顶层我始终无法成功…这看起来应该是个简单的步骤。

例如:

package main

var num int

num  = 5      // 语法错误:函数体外的非声明语句

func main() {

	    // num = 5  // 这在函数级别有效

	    println(num)
}

更多关于Golang中如何在函数外部给未初始化的变量赋值的实战教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

引用自 https://golang.org/doc/

语言规范

官方的 Go 语言规范。

更多关于Golang中如何在函数外部给未初始化的变量赋值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


bevo009:

发现了那个怪癖

哪个怪癖?

我真的不知道有任何编译语言会允许这样的结构,即使有,我敢打赌社区会对此发出警告并持反对态度。

请查看 Go 语言教程。带初始化器的变量在第一章中有所涉及 🙂

https://tour.golang.org/basics/9

如你所说,只能在初始化时或在函数内为变量赋值。

NobbZ: 这在语言语法中有所记载,因为它不允许在函数外部进行此类赋值。

你有相关说明的链接吗?我想阅读并记录这个信息。

我只是在梳理 Go 的规则而已。我整理了一份包含所有可能的变量赋值/重新赋值规则的页面,然后发现了这个特性,但找不到任何解释说明。

这在语言语法中有所说明,因为它不允许在函数外部进行此类赋值。

原因很简单。如果你能够拆分这些内容,可能会忘记初始化。或者某个开发者可能没有看到你在后面一百行处初始化了变量,然后又在其他地方进行了初始化。两者都在"顶层"进行,而顶层没有顺序概念,那么哪个会生效呢?

再说一遍,你究竟为什么要拆分它?通常没有理由这样做。

在顶层作用域中不存在"稍后初始化"的概念。

你可以在声明时初始化,或者在 init 函数或其他函数调用中初始化,但如果没有外围函数,你不能在第3行声明而在第4行赋值/初始化。

说实话,我也看不出有什么必要做这样的事情…

func main() {
    fmt.Println("hello world")
}

“带有初始化器的变量 var 声明可以包含初始化器,每个变量一个。 如果提供了初始化器,则可以省略类型;变量将采用初始化器的类型。”

我当然先读了那段内容,但这完全没能解释我的问题,即稍后初始化顶层变量的问题。 我认为文档中没有任何地方解释过这一点。如果有的话,请给我指出来。

那么,我能否声明一个没有值的顶层变量,然后在稍后初始化它?

如果可以,为什么没有任何地方记录这一点?如果你来自其他编程语言,这似乎是预期的行为。

NobbZ:

在顶层不存在"稍后初始化"的概念。 你要么在声明时初始化,要么在init函数或其他函数调用中初始化,但不能在第3行声明然后在第4行赋值/初始化,除非有包围函数。

感谢回答,这是我从实验中得出的结论,但想从有Go经验的人那里得到确认…你知道为什么这样设计吗?毕竟在函数级别你是可以在声明后初始化的。

这种特定行为是否有在任何地方正式记录,无论是在官方文档还是其他地方?我找了很久但什么都没找到。

Go语言规范:包初始化Go包初始化函数与主函数执行顺序详解 可能更接近您想阅读的内容,这些资料能帮助您深入理解包的初始化机制。

关于"不能在声明之外赋值变量"的所谓"规则",其实并不存在这样的规定。实际情况是语言本身没有提供相应的语法支持。这就像汽车不能飞行一样——并没有明文规定"禁止汽车飞行",但由于缺乏机翼、喷气引擎等必要组件,它自然无法翱翔天际。同样地,Go语言在初始化完成后(除init函数或其他函数内部外)就没有提供任何语法来支持包级变量的赋值操作。

关于"不能在声明之外赋值变量"的规则,实际上并不存在这样的规则。而是根本没有办法做到这一点。可以把它想象成一辆不能飞的汽车;并没有规则规定"这辆汽车不能飞",但由于它没有机翼、喷气发动机等,所以它就是飞不起来。类似地,Go语言只是没有任何语法允许你在初始化后(在init函数或其他函数之外)对包级变量进行赋值。

不过Go语言之旅确实解释了短变量声明不能在函数外使用,这是类似的情况,所以我不确定汽车类比是否成立。

https://tour.golang.org/basics/10

在函数外,每个语句都以关键字(var、func等)开头,因此:=结构不可用。

总之,感谢Jon澄清了文档中没有解释这一点,我现在停止寻找了。也感谢你提供的链接。😊

在Go语言中,顶层作用域只允许声明语句,不允许执行语句。变量赋值属于执行语句,因此不能在函数外部直接进行。

以下是正确的做法:

package main

// 方式1:在声明时直接初始化
var num int = 5

// 方式2:使用初始化函数
var num2 int

func init() {
    num2 = 10
}

func main() {
    println(num)   // 输出: 5
    println(num2)  // 输出: 10
}

或者使用短变量声明在函数内部赋值:

package main

var num int

func main() {
    num = 5  // 在函数内部赋值
    println(num)  // 输出: 5
}

如果需要复杂的初始化逻辑,可以使用init()函数:

package main

var config map[string]string

func init() {
    config = make(map[string]string)
    config["host"] = "localhost"
    config["port"] = "8080"
}

func main() {
    println(config["host"])  // 输出: localhost
}

Go语言设计上要求在顶层作用域只能包含声明语句,执行语句必须放在函数内部,这是语言规范的一部分。

回到顶部