理解 go 复合字面量

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)

Gri*_*kin 7

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