英文:
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
}
这样写非常清晰,对吧?我们只是将原始代码分成了两个步骤。但这并不完全相同。当以这种方式编写时,h
和 ok
变量在 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, seth
and setok
to true. - If
ok
is true, then call the functionh
. - Otherwise, write the URL to the response (and do nothing further).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论