mon*_*mon 10 go composite-literals
为什么对f 的函数值赋值不是复合文字?
Go lang规范复合文字如下所述,因此函数值不能用复合文字构造。
复合文字为结构体、数组、切片和映射构造值,并在每次求值时创建一个新值
但是,代码中对f 的函数值赋值看起来像是func() int类型的复合文字表达式。
是否存在无法将函数对象构造为复合文字的原因?
package main
import (
"fmt"
)
func main(){
var x int = 0
var f func() int
f = func() int{ x++; return x * x } // <---- Why this cannot be a composite literal?
fmt.Println(f()) // 1
fmt.Println(f()) // 4
fmt.Println(f()) // 9
// Define a type for "func() int" type
type SQUARE func() int
g := SQUARE{ x++; return x * x} // <--- Error with Invalid composite literal type: SQUARE
fmt.Println(g())
}
Run Code Online (Sandbox Code Playgroud)
f = func() int{ x++; return x * x }看起来像复合文字吗?并不真地)
正如规范所述:
复合文字为结构、数组、切片和映射构造值...它们由文字类型和后跟大括号元素列表组成。
为了使这个陈述更清楚,这里是复合文字的产生规则:
CompositeLit = LiteralType LiteralValue .
Run Code Online (Sandbox Code Playgroud)
你可以看到,产生式规则是LiteralValue:
LiteralValue = "{" [ ElementList [ "," ] ] "}" .
Run Code Online (Sandbox Code Playgroud)
而且FunctionBody,看起来根本不像这样。基本上,它是以下列表Statement:
FunctionBody = Block .
Block = "{" StatementList "}" .
StatementList = { Statement ";" } .
Run Code Online (Sandbox Code Playgroud)
我无法找到任何有记录的答案,但最简单的假设是主要原因是:
type SquareFunc func() int
type Square struct {
Function SquareFunc
}
func main() {
f := SquareFunc{ return 1 }
s := Square{ buildSquareFunc() }
}
Run Code Online (Sandbox Code Playgroud)
s:= ...行(应该是复合类型)很容易与第一行混淆。
Signature。如果您可以为函数构造复合文字,您将如何定义它的参数和返回参数名称?您可以在类型定义中定义名称 - 但这会导致不灵活性(有时您想使用不同的参数名称)和类似的代码:type SquareFunc func(int x) int
func main() {
x := 1
f := SquareFunc{
x++
return x * x
}
f(2)
}
Run Code Online (Sandbox Code Playgroud)
x看起来太不清楚,因为它实际使用的变量并不明显。
小智 1
你需要格式化它。
package main
import (
"fmt"
)
func main(){
var x int = 0
var f func() int
f = (func() int{ x++; return x * x }) // <---- Why this cannot be a composite literal?
fmt.Println(f()) // 1
fmt.Println(f()) // 4
fmt.Println(f()) // 9
// Define a type for "func() int" type
type SQUARE func() int
g := SQUARE(func()int{ x++; return x * x}) // <--- Error with Invalid composite literal type: SQUARE
fmt.Println(g())
}
Run Code Online (Sandbox Code Playgroud)
f使用包装您的变量()。在这种情况下,您需要在开始功能代码之前SQUARE编写func() int