麻烦理解go函数调用语法

时间:2016-03-25 19:33:25

标签: go

我找到了这个例子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())
}

我对这条线非常困惑:

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

首先,在ok的结果被分配后,如何在语法上声明route()

第二,如果h返回route(),如何在ok ???的定义中使用

我对此深感困惑。地鼠,请帮忙。

2 个答案:

答案 0 :(得分:4)

在Tour of Go中查看this page。它解释说:

  

if类似,h, ok := route[request.URL.String()]; ok { ... } 语句可以以在条件之前执行的短语句开头。

鉴于你的例子:

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

简短陈述是;ok之后标记了短语的结束。随后的{...}是条件。如果为true,则执行代码块ok。在该代码块中,您可以使用在short语句中分配的所有变量。

  

首先,在route()的结果被分配后,如何在语法上声明ok

分配后未声明

h is returned by。它是一个布尔值,用于条件。

  

第二,如果, how can it be used in the definition of route()ok ok` ???

这不是if的定义。它是h, ok := route[request.URL.String()] if ok { h(writer, request) return } 语句的代码块。

考虑这种替代方案,几乎相当于写作风格:

h

这很清楚,对吗?我们只是将原始代码拆分为两个步骤。但这不一样。以这种方式编写时,okif变量在if语句后可见。这是不可取的。最小化变量的可见性(也称为实时时间)是一种很好的做法。变量可见的时间越长,漏洞窗口的时间越长,在此期间可能会意外误用。 Go的这种语法真的很棒,天才,而且我不知道这种if语句可能的其他语言。

另请参阅Effective Go abstract class Warehouse<T> { private StockLoader<T> loader; private List<T> stock; protected setStockLoader(StockLoader loader) { this.loader = loader; } protected List<T> getStock() { return stock; } public void load() { stock = loader.load(); } abstract showStock(); } class WheatWH extends Warehouse<Wheat> { @Override public void showStock() { // Print stocck with getStock() returns Wheat; } } class RiceWH extends Warehouse<Rice> { @Override public void showStock() { // Print stocck with getStock() returns Rice; } } interface List<T> StockLoader<T>() { public List<T> load(); } class PlainStockLoader implements StockLoader<Wheat>{ public List<Wheat> load() { //Code } } class Rice { ..... } class Wheat { .... } 声明中的部分。

答案 1 :(得分:3)

首先:你应该浏览Go Tour - 特别是地图上的部分:https://tour.golang.org/moretypes/16

这里的“逗号,确定”成语用于检查地图中是否存在密钥。对不存在的密钥进行查找会发生混乱(并可能导致应用程序崩溃)。

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

  • 如果request.URL.String()存在,请设置h并将ok设置为true。
  • 如果ok为真,则调用函数h
  • 否则,请将URL写入响应(并且不做任何进一步的操作)。