为 struct 字段赋值时.

    FlagSet: (func() *flag.FlagSet {
        fs := newFlagSet("configure")
        return fs
    })(),

我认为这等同于只调用newFlagSet("configuration").这样写有什么好处呢?

在阅读资料时提出问题.需要知道他为什么写成这样.

推荐答案

quick search之后,这个代码来自tailscale/tailscale, cmd/tailscale/cli/configure.go#var configureCmd = &ffcli.Command{}

var configureCmd = &ffcli.Command{
    Name:      "configure",
    ShortHelp: "[ALPHA] Configure the host to enable more Tailscale features",
    LongHelp: strings.TrimSpace(`
The 'configure' set of commands are intended to provide a way to enable different
services on the host to use Tailscale in more ways.
`),
    FlagSet: (func() *flag.FlagSet {
        fs := newFlagSet("configure")
        return fs
    })(),
    Subcommands: configureSubcommands(),
    Exec: func(ctx context.Context, args []string) error {
        return flag.ErrHelp
    },
}

该代码使用function literal(匿名函数),然后立即调用该函数.

这就是众所周知的Immediately-Invoked Function Expression (IIFE)分.这在诸如JavaScript之类的语言中更为常见,但在Go中也很有用.

In Go, IIFE allows you to isolate a piece of logic that produces a value, creating a scoped environment for variables that will not pollute the surrounding namespace.
The variables used within the anonymous function (fs in this case) do not escape into the surrounding code. This makes the code easier to reason about, as the variables live only as long as they are needed.

虽然FlagSet: newFlagSet("configure"),确实相当于FlagSet: (func() *flag.FlagSet { fs := newFlagSet("configure"); return fs})(),但第二种形式的一些优势可能是:

  • 可扩展性:如果将来对newFlagSet("configure")的修改需要更复杂的操作或计算,这些更改可以很容易地合并到匿名函数中,而不会改变configureCmd的 struct .
  • 调试:可以在调试会话期间轻松地注释掉、记录或修改封装的逻辑,而不会干扰周围的代码.

然而,看看tailscale code个人,这一特定的生活使用似乎仅限于这一次.

Go相关问答推荐

有没有更简单的方法在Go中编写这个逻辑?

Go程序在并发Forking 循环中停留在syscall.Wait4

Kafka消费者在需要时不会暂停

按键值排序字符串- Golang

如何在S汇编器中更高效地将全局数据加载到霓虹灯寄存器?

如何修复proxyconnect tcp:tls:第一条记录看起来不像tls握手

如何修复 Go 中协议缓冲区定义中重新定义的字段?

Json.Unmarshal() 和 gin.BindJson() 之间的区别

仅使用公共 api 对 alexedwards/scs 进行简单测试

为什么我只收到部分错误而不是我启动的 goroutines 的所有错误?

如何将验证器标记添加到嵌套字段

在 Golang 中查看目录是否可写的跨平台方式?

assert: mock: I don't know what to return because the method call was unexpected 在 Go 中编写单元测试时出错

如何使用带有方法的字符串枚举作为通用参数?

使用 `didip/tollbooth` 限制每小时最大请求数

使用 oklog/run 来自 Go 编译器的错误(无值)用作值

Go:用于 XML 解码的嵌套 struct 中的提升字段

函数的递归调用以 goroutine 和惯用方式开始,以在所有工作 goroutine 完成时继续调用者

如何发送带有登录数据的 GET 请求并将 cookie 数据保存到 txt 文件?

是否可以动态加载 Go 代码?