亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

defer 關鍵字在 Go 中的工作原理

defer 關鍵字在 Go 中的工作原理

Go
米脂 2023-07-31 16:39:40
存在一個問題,提示用戶輸入票價年齡,但當if輸入的年齡高于 13 歲時,報表僅打印 9.99:嘗試過:=,并且fmt.Println(ticketPrice == 19.99)。如果有人有其他建議,請告訴我。package mainimport "fmt"func main() {    var age int    var ticketprice float64    defer fmt.Println("Your age is:", getAge(age)) // calls getAge    defer fmt.Println("Your ticket price is:", printTicket(age,        ticketprice)) // calls printTicket}func printTicket(age int, ticketPrice float64) float64 {    if age <= 13 {        ticketPrice = 9.99 // only calls 9.99, not anything else    } else if age > 13 && age < 65 {        ticketPrice = 19.99 // not being called?    } else if age >= 65 {        ticketPrice = 12.99 // not being called?    }    return ticketPrice // returns ticket price} // Whole function is not being used for some reason. Only returns 9.99, nothing elsefunc getAge(age int) int {    fmt.Println("What is your age?")    fmt.Scan(&age)    for age < 0 || age > 100 {        fmt.Println("That cannot be, please enter your age again")        fmt.Scan(&age)    }    return age}func getName(name string) string {    fmt.Println("What is your name?")    fmt.Scan(&name)    return name}
查看完整描述

1 回答

?
尚方寶劍之說

TA貢獻1788條經驗 獲得超4個贊

請參閱Defer_statements:

每次執行“defer”語句時,調用的函數值參數都會照常評估并重新保存,但不會調用實際函數。相反,延遲函數會在周圍函數返回之前立即調用,調用順序與延遲函數相反。也就是說,如果周圍函數通過顯式 return 語句返回,則延遲函數將在該 return 語句設置任何結果參數之后但在函數返回到其調用者之前執行。如果延遲函數值求值為 nil,則在調用該函數時(而不是執行“defer”語句時)會發生執行混亂。

為了理解評估順序,讓我們嘗試一下:


defer having()(fun("with Go."))

讓我們運行它并閱讀評估順序的代碼注釋:


package main


import "fmt"


func main() {

? ? defer having()(fun("with Go."))

? ? fmt.Print("some ") // evaluation order: 3

}

func having() func(string) {

? ? fmt.Print("Go ") // evaluation order: 1

? ? return funWithGo

}

func fun(msg string) string {

? ? fmt.Print("have ") // evaluation order: 2

? ? return msg

}

func funWithGo(msg string) {

? ? fmt.Println("fun", msg) // evaluation order: 4

}

輸出:


Go have some fun with Go.

這樣就更漂亮了,同樣的結果,只需將所有函數替換為匿名函數即可:


package main


import "fmt"


func main() {

? ? defer func() func(string) {

? ? ? ? fmt.Print("Go ") // evaluation order: 1

? ? ? ? return func(msg string) {

? ? ? ? ? ? fmt.Println("fun", msg) // evaluation order: 4

? ? ? ? }

? ? }()(func(msg string) string {

? ? ? ? fmt.Print("have ") // evaluation order: 2

? ? ? ? return msg

? ? }("with Go."))

? ? fmt.Print("some ") // evaluation order: 3

}

我希望這可以幫助您了解其defer工作原理:代碼的工作

版本,內部有足夠的文檔(注意首先評估的參數和調用將推遲到以相反順序返回的函數):deferfmt.Println


package main


import "fmt"


func printTicket(age int) float64 {

? ? fmt.Println("...order is 2...")

? ? switch {

? ? case age <= 13:

? ? ? ? return 9.99

? ? case age > 13 && age < 65:

? ? ? ? return 19.99

? ? default:

? ? ? ? return 12.99

? ? }

}


func main() {

? ? age := 999

? ? defer fmt.Println("...order is 4...Your age is:", getAge(&age))

? ? defer fmt.Println("...order is 3...Your ticket price is:", printTicket(age))

}


func getAge(age *int) int {

? ? fmt.Println("...order is 1...")

? ? fmt.Print("Enter age=")

? ? fmt.Scanln(age)

? ? return *age

}


輸出:


...order is 1...

Enter age=999

...order is 2...

...order is 3...Your ticket price is: 12.99

...order is 4...Your age is: 999


查看完整回答
反對 回復 2023-07-31
  • 1 回答
  • 0 關注
  • 144 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號