为了账号安全,请及时绑定邮箱和手机立即绑定

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 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信