go - 为什么在 Golang 的闭包体后添加 "()"?

标签 go closures

我正在阅读 The Go Programming Language Specifications,发现自己在闭包体之后并没有真正理解“()”:

函数字面量中:

func(ch chan int) { ch <- ACK }(replyChan)`

Defer statements的例子中:

// f returns 1
func f() (result int) {
    defer func() {
        result++
    }() // why and how?
    return 0
}

我不清楚在闭包体之后添加和使用“()”的原因,希望有人能解释清楚。

最佳答案

并不是() 必须(仅)在defer 中的closure 之后添加。 defer statement 的语言规范要求它的“表达式”总是必须是函数调用。

为什么会这样?与任何其他功能相同,无论是否在“延迟”中:

考虑:

func f() int { return 42 }

a := f

b := f()

第一个表达式 RHS 是一个函数值。在第二个版本中,RHS 是 函数返回的值 - 即一个函数调用。

以下的语义也是如此:

defer f

defer f()

除了第一个版本在'defer'的上下文中没有意义,因此规范提到它必须是第二种形式(仅)。

恕我直言,这也更容易学习,因为上面讨论的函数调用在“defer”语句之外是正交性的。

还要注意,函数调用不仅是fn-expr后跟(),而是表达式列表一般在括号内(包括一个空列表)。两者之间有很大区别:

for i := range whatever {
        defer func() { fmt. Println(i) }()
}

for i := range whatever {
        defer func(n int) { fmt. Println(n) }(i)
}

第一个版本在闭包执行时打印'i'的值,第二个版本在defer语句执行时打印'i'的值 em> 执行。

关于go - 为什么在 Golang 的闭包体后添加 "()"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16008604/

相关文章:

go - 使用 neo4j go 驱动程序编译 neo4j 代码的问题

go - 当避免使用全局变量 (/state) 时,我发现自己将对象向后链接到其父对象。我这样做对吗?如果不解释为什么?还有什么?

go - 第三方库(闭源)

go - HyperLedger-Fabric ChainCode 部署 - Base64 错误

java - Groovy GroupBy 变量键集

ios - 在函数中使用闭包

JavaScript 闭包问题又来了!

Golang(初学者): Avoiding duplicate functions to deal with strings or ints

node.js - NodeJS 回调 - 访问 'res'