在 Go 語言(Golang)中,變量的作用域是一個非常重要的概念,它決定了變量在程序中的可見性和生命周期。Go 語言的作用域規(guī)則相對簡單直觀,主要基于詞法作用域(也稱為靜態(tài)作用域或靜態(tài)解析作用域)。
全局變量是在函數(shù)外部聲明的變量,它們在整個包內(nèi)都是可見的,但是只能被包內(nèi)的代碼訪問(除非使用了export
關(guān)鍵字,但在 Go 中通常是通過首字母大寫來實現(xiàn)公共可見性)。全局變量的生命周期貫穿整個程序執(zhí)行期間。
package main
import "fmt"
var globalVar = "I am a global variable"
func main() {
fmt.Println(globalVar)
}
局部變量是在函數(shù)內(nèi)部聲明的變量,它們的作用域限制在聲明它們的代碼塊(通常是一個函數(shù)或函數(shù)內(nèi)的控制結(jié)構(gòu),如if
、for
、switch
等)內(nèi)。一旦離開這個作用域,局部變量將不再可用。
package main
import "fmt"
func main() {
var localVar = "I am a local variable"
fmt.Println(localVar)
// localVar 在這里之后不再可用
}
函數(shù)參數(shù)是傳遞給函數(shù)的局部變量,它們的作用域限于函數(shù)體內(nèi)。函數(shù)參數(shù)在函數(shù)被調(diào)用時接收外部傳入的值,并在函數(shù)執(zhí)行期間使用這些值。
package main
import "fmt"
func greet(name string) {
fmt.Println("Hello, " + name)
// name 僅在 greet 函數(shù)內(nèi)可用
}
func main() {
greet("World")
}
在 Go 中,如果一個代碼塊(如一個函數(shù)或一個控制結(jié)構(gòu))被另一個代碼塊包含,內(nèi)部代碼塊可以訪問外部代碼塊中聲明的變量,但不能直接訪問外部代碼塊之外的變量。這被稱為嵌套作用域。
package main
import "fmt"
func outerFunction() {
var outerVar = "I am outer"
func innerFunction() {
fmt.Println(outerVar) // 可以訪問 outerVar
}
innerFunction()
}
func main() {
outerFunction()
// innerFunction() 和 outerVar 在這里都不可用
}
在Go語言中,形式參數(shù)(簡稱形參)是函數(shù)定義時出現(xiàn)的參數(shù),它們可以看作是函數(shù)內(nèi)部的占位符,用于接收函數(shù)調(diào)用時傳遞進(jìn)來的實際參數(shù)(簡稱實參)的數(shù)據(jù)。形參在函數(shù)被調(diào)用之前并不占用實際的內(nèi)存空間,也沒有具體的值,只有在函數(shù)被調(diào)用時,才會根據(jù)實參的值進(jìn)行初始化。
局部性:形參是函數(shù)內(nèi)部的局部變量,它們的生命周期僅限于函數(shù)執(zhí)行期間。一旦函數(shù)執(zhí)行完畢,形參所占用的內(nèi)存空間就會被釋放。
初始化:形參在函數(shù)被調(diào)用時,會根據(jù)實參的值進(jìn)行初始化。如果實參是通過值傳遞的方式傳遞的,那么形參會得到實參值的一份拷貝;如果實參是通過引用傳遞(在Go中通常是通過指針傳遞實現(xiàn)的)的方式傳遞的,那么形參會指向?qū)崊⑺玫膬?nèi)存地址。
不可變性(對于值傳遞):在默認(rèn)情況下,Go語言中的函數(shù)參數(shù)是通過值傳遞的方式傳遞的。這意味著在函數(shù)內(nèi)部對形參的修改不會影響到實參的值。因為形參是實參值的一份拷貝,所以對形參的修改實際上是在修改這份拷貝,而不是實參本身。
可變性(對于引用傳遞):雖然Go語言本身不支持直接的引用傳遞,但可以通過傳遞指針的方式實現(xiàn)類似的效果。當(dāng)實參是指針類型時,形參也會是指針類型,并指向?qū)崊⑺玫膬?nèi)存地址。此時,在函數(shù)內(nèi)部對形參所指向的內(nèi)存地址中的內(nèi)容進(jìn)行修改,就會影響到實參所引用的內(nèi)容。
package main
import "fmt"
// 值傳遞示例
func changeValue(a int) {
a += 100 // 修改形參a的值,不會影響實參
}
// 引用傳遞(通過指針)示例
func changeReference(a *int) {
*a += 100 // 修改形參a所指向的值,即實參的值
}
func main() {
x := 10
changeValue(x) // x的值不會改變
fmt.Println(x) // 輸出: 10
changeReference(&x) // x的值會改變
fmt.Println(x) // 輸出: 110
}
在上面的示例中,changeValue
函數(shù)通過值傳遞接收一個int
類型的參數(shù),因此在函數(shù)內(nèi)部對參數(shù)的修改不會影響到實參。而changeReference
函數(shù)通過指針傳遞接收一個int
類型的指針參數(shù),因此在函數(shù)內(nèi)部對指針?biāo)赶虻膬?nèi)容的修改會影響到實參。
上一篇: Golang 語言函數(shù)
下一篇: Golang 語言數(shù)組