索引:https://waterflow.link/articles/
成都網(wǎng)絡(luò)公司-成都網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司10多年經(jīng)驗成就非凡,專業(yè)從事網(wǎng)站建設(shè)、網(wǎng)站設(shè)計,成都網(wǎng)頁設(shè)計,成都網(wǎng)頁制作,軟文發(fā)稿,1元廣告等。10多年來已成功提供全面的成都網(wǎng)站建設(shè)方案,打造行業(yè)特色的成都網(wǎng)站建設(shè)案例,建站熱線:13518219792,我們期待您的來電!
在 Go 中,在塊中聲明的變量名可以在內(nèi)部塊中重新聲明。 這種稱為變量陰影的原理很容易出現(xiàn)常見錯誤。
以下示例顯示了由于變量陰影而導(dǎo)致的意外副作用。 它以兩種不同的方式獲取課件信息,根據(jù)printLog這個布爾值,判斷是否打印日志而走到不同的代碼分支:
package main
import "fmt"
type Courseware struct {
Id int64
Name string
Code string
}
func main() {
printLog := false
var courseware *Courseware // 1
if printLog {
courseware , err := getCoursewareAndLog() // 2
if err != nil {
fmt.Println("get courseware err: ", err)
}
fmt.Println(courseware) // 3
} else {
courseware, err := getCourseware() // 2
if err != nil {
fmt.Println("get courseware err: ", err)
}
fmt.Println(courseware) // 3
}
fmt.Println(courseware) // 4
}
func getCoursewareAndLog() (*Courseware, error) {
fmt.Println("打印日志。。。")
return &Courseware{
Id: 1,
Name: "多媒體課件",
Code: "CW100",
}, nil
}
func getCourseware() (*Courseware, error) {
return &Courseware{
Id: 2,
Name: "多媒體課件1",
Code: "CW101",
}, nil
}
我們可以分析下上面的代碼:
:=
,說明在代碼塊內(nèi)部我們重新聲明了一個變量courseware,這個并不是外部的courseware變量。如果現(xiàn)在我們用的是PHP語言,那這個絕對不會出現(xiàn)任何問題。if代碼塊內(nèi)部會打印出獲取課件的詳情,外部也會打印出獲取課件的詳情。對應(yīng)上面代碼中的3、4。畢竟PHP是世界上最好的語言么。
但是在上面的結(jié)果中,3會正常打印課件詳情,4會打印if代碼塊外部的courseware,所以是nil。
我們看下打印的結(jié)果:
go run 1.go
&{2 多媒體課件1 CW101}
這就是所謂的變量陰影。
那我們該如何修改上面的代碼使程序變得正常呢?
其實有2種方式修改:
增加一個臨時變量
package main
import "fmt"
type Courseware struct {
Id int64
Name string
Code string
}
func main() {
printLog := false
var courseware *Courseware // 1
if printLog {
cw , err := getCoursewareAndLog() // 2
courseware = cw // 增加臨時變量
if err != nil {
fmt.Println("get courseware err: ", err)
}
fmt.Println(courseware) // 3
} else {
cw, err := getCourseware() // 2
courseware = cw // 增加臨時變量
if err != nil {
fmt.Println("get courseware err: ", err)
}
fmt.Println(courseware) // 3
}
fmt.Println(courseware) // 4
}
func getCoursewareAndLog() (*Courseware, error) {
fmt.Println("打印日志。。。")
return &Courseware{
Id: 1,
Name: "多媒體課件",
Code: "CW100",
}, nil
}
func getCourseware() (*Courseware, error) {
return &Courseware{
Id: 2,
Name: "多媒體課件1",
Code: "CW101",
}, nil
}
看下打印結(jié)果,正常輸出:
go run 1.go
&{2 多媒體課件1 CW101}
&{2 多媒體課件1 CW101}
不使用:=,err在外部初始化
package main
import "fmt"
type Courseware struct {
Id int64
Name string
Code string
}
func main() {
printLog := false
var courseware *Courseware // 1
var err error // err放到外層
if printLog {
courseware , err = getCoursewareAndLog() // 2 =號賦值
if err != nil {
fmt.Println("get courseware err: ", err)
}
fmt.Println(courseware) // 3
} else {
courseware, err = getCourseware() // 2 =號賦值
if err != nil {
fmt.Println("get courseware err: ", err)
}
fmt.Println(courseware) // 3
}
fmt.Println(courseware) // 4
}
func getCoursewareAndLog() (*Courseware, error) {
fmt.Println("打印日志。。。")
return &Courseware{
Id: 1,
Name: "多媒體課件",
Code: "CW100",
}, nil
}
func getCourseware() (*Courseware, error) {
return &Courseware{
Id: 2,
Name: "多媒體課件1",
Code: "CW101",
}, nil
}
看下結(jié)果,正常輸出:
go run 1.go
&{2 多媒體課件1 CW101}
&{2 多媒體課件1 CW101}