延迟关键字在Go中的工作方式 [英] How defer keyword works in Go

查看:38
本文介绍了延迟关键字在Go中的工作方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

存在一个提示用户输入票价价格年龄的问题,但是 if 语句仅在输入年龄超过13岁时才打印9.99:

Having an issue where the user is prompt to enter an age for the ticket price, but if statement only prints 9.99 when the entered age is above 13:

尝试:= fmt.Println(ticketPrice == 19.99).
如果有人有其他建议,请告诉我.

Tried :=, and fmt.Println(ticketPrice == 19.99).
If anyone has another suggestion, let me know.

package main

import "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 else

func 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
}

推荐答案

请参见 Defer_statements :

每次执行"defer"语句时,调用的函数值参数

Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred. That is, if the surrounding function returns through an explicit return statement, deferred functions are executed after any result parameters are set by that return statement but before the function returns to its caller. If a deferred function value evaluates to nil, execution panics when the function is invoked, not when the "defer" statement is executed.

此外,请参见 go 关键字

Also, see an example for the go keyword

要了解评估顺序,请尝试以下操作:

To understand the evaluation order, let's try this:

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

让我们运行,并阅读评估顺序的代码注释:

Let's run this and read the code comments for the evaluation order:

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.

更加美观,其结果相同,只是将所有函数替换为匿名功能:

This is even more beautiful, with the same result, just replace all functions with anonymous functions:

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 的工作方式:
包含足够文档的代码的工作版本(请注意 def fmt.Println 的code>参数将延迟以相反的顺序返回到函数):


I hope this helps you to understand how the defer works:
A working version of your code with enough documentation inside (Note defer parameters evaluated first in place and call to fmt.Println will be deferred to function return in reverse order):

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

这篇关于延迟关键字在Go中的工作方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆