Действительно ли f = func() int{ x++; return x * x }
выглядит как составной литерал?
Не совсем)
Как spe c состояния :
Composite литералы конструируют значения для структур, массивов, срезов и карт ... Они состоят из типа литерала, за которым следует список элементов в скобках.
Чтобы сделать это утверждение более понятным, вот производственное правило для составного литерала:
CompositeLit = LiteralType LiteralValue .
Вы можете видеть, что производственное правило для LiteralValue
:
LiteralValue = "{" [ ElementList [ "," ] ] "}" .
и FunctionBody
, совсем не похоже на это. По сути, это список Statement
:
FunctionBody = Block .
Block = "{" StatementList "}" .
StatementList = { Statement ";" } .
Почему функция не может быть построена как составной литерал?
Я не смог найти никакого документированного ответа на этот вопрос, но простейшим предположением будет то, что основными причинами являются:
- Избегайте путаницы. Вот пример, если бы было разрешено создать составной литерал для функции:
type SquareFunc func() int
type Square struct {
Function SquareFunc
}
func main() {
f := SquareFunc{ return 1 }
s := Square{ buildSquareFunc() }
}
s:= ...
строка (которая должна быть составного типа) могла бы быть легко перепутана с 1-й строкой.
- Помимо тела, у функции есть еще одна важная вещь -
Signature
. Если бы вы могли создать составной литерал для функции, как бы вы определили его аргументы и вернули имена параметров? Вы можете определить имена в определении типа - но это может привести к негибкости (иногда вы захотите использовать разные имена параметров) и коду вроде:
type SquareFunc func(int x) int
func main() {
x := 1
f := SquareFunc{
x++
return x * x
}
f(2)
}
будет выглядеть слишком неясным, поскольку это не будет очевидно, какую переменную x
она на самом деле использует.