我有困难理解go函数调用语法。

huangapple go评论92阅读模式
英文:

Trouble understanding go function call syntax

问题

我在这里找到了这个例子:链接:

func(*myHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {

    // 这行代码是做什么用的??
    if h, ok := route[request.URL.String()]; ok {
        h(writer, request)
        return
    }

    io.WriteString(writer, "my server: " + request.URL.String())
}

我对这行代码感到非常困惑:

if h, ok := route[request.URL.String()]; ok { h(writer, request) }

首先,声明 ok 在它被赋值为 route() 的结果之后,这在语法上是有效的吗?

其次,如果 h 是由 route() 返回的,它如何在定义 ok 的时候使用?

我对此感到非常困惑。Go 语言的开发者,请帮帮忙。

英文:

I found this example here:

func(*myHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {

    // What does this line do??
    if h, ok := route[request.URL.String()]; ok {
        h(writer, request)
        return
    }

    io.WriteString(writer, "my server: " + request.URL.String())
}

I am extremely puzzled by this line:

if h, ok := route[request.URL.String()]; ok { h(writer, request) }

first off, how can it be valid syntactically to declare ok after it is assigned to the result of route()?

second, if h is returned by route(), how can it be used in the definition of ok???

I am thoroughly confused by this. Gophers, please help.

答案1

得分: 4

请看一下这个页面在Go之旅中的内容。它解释了以下内容:

for 循环一样,if 语句可以以一个短语句开始,在条件之前执行。

根据你的例子:

h, ok := route[request.URL.String()]; ok { ... }

短语句是 h, ok := route[request.URL.String()]。分号 ; 标志着短语句的结束。之后的 ok 是条件。如果条件为真,则执行代码块 {...}。在该代码块中,你可以使用在短语句中分配的所有变量。

首先,如何在将 ok 分配给 route() 的结果之后声明它是有效的语法?

ok 在分配之后并没有被声明。它是一个布尔值,在条件中使用。

其次,如果 h 是由 route() 返回的,它如何在定义 ok 的过程中使用?

这不是定义 ok。这是 if 语句的代码块。

考虑一下这种几乎等价的写法:

h, ok := route[request.URL.String()]
if ok {
    h(writer, request)
    return
}

这样写非常清晰,对吧?我们只是将原始代码分成了两个步骤。但这并不完全相同。当以这种方式编写时,hok 变量在 if 语句之后仍然可见。这是不可取的。最小化变量的可见性(也称为生存时间)是一种良好的实践。变量可见的时间越长,漏洞窗口(在此期间变量可能被意外误用)就越长。Go语言的这种语法真的很棒,很巧妙,我不知道还有其他哪种语言可以实现这种类型的 if 语句。

还可以参考Effective Go中关于 if 语句的部分。

英文:

Take a look at this page in Tour of Go. It explains that:

> Like for, the if statement can start with a short statement to execute before the condition.

Given your example:

> h, ok := route[request.URL.String()]; ok { ... }

The short statement is h, ok := route[request.URL.String()]. The ; after marks the end of the short statement. The ok that follows is the condition. If true, then the code block {...} is executed. In that code block you can use all the variables that were assigned in the short statement.

> first off, how can it be valid syntactically to declare ok after it is assigned to the result of route()?

ok is not declared after it is assigned. It is a boolean value, used in the condition.

> second, if h is returned by route(), how can it be used in the definition of ok`???

It's not definition of ok. It's the code block of the if statement.

Consider this alternative, almost equivalent writing style:

h, ok := route[request.URL.String()]
if ok {
    h(writer, request)
    return
}

This is perfectly clear, right? We just split the original code to two steps. But this is not the same. When writing this way, the h and ok variables are visible after the if statement. This is not desirable. It's a good practice to minimize the visibility of variables (also known as the live time). The longer a variable is visible, the longer the window of vulnerability during which it can be accidentally misused. This syntax of Go is truly great, genius, and I don't know a single other language where this kind of if statement is possible.

See also the section on the if statement in Effective Go.

答案2

得分: 3

首先,你应该完成Go Tour的学习,特别是关于Maps的部分:https://tour.golang.org/moretypes/16

这里的"comma, ok"习惯用法旨在检查键是否存在于map中。对不存在的键进行查找将导致panic(并可能导致应用程序崩溃)。

if h, ok := route[request.URL.String()]; ok { h(writer, request) }

  • 如果request.URL.String()存在,则设置h并将ok设置为true。
  • 如果ok为true,则调用函数h
  • 否则,将URL写入响应(并不执行其他操作)。
英文:

Firstly: you should run through the Go Tour - specifically the section on Maps: https://tour.golang.org/moretypes/16

The "comma, ok" idiom here is designed to check that the key exists in the map. Doing a lookup on a non-existent key will panic (and likely crash your application).

if h, ok := route[request.URL.String()]; ok { h(writer, request) }

  • If request.URL.String() exists, set h and set ok to true.
  • If ok is true, then call the function h.
  • Otherwise, write the URL to the response (and do nothing further).

huangapple
  • 本文由 发表于 2016年3月26日 03:33:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/36226711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定