4

我想以这种方式链接命令:

var cmdGroups = []*commands.CmdGroup {
    commands.MakeCmdGroup("foo", cmd1, cmd2, cmd3).AddConstraint(cmd1, cmd2).AddConstraint(cmd2, cmd1, cmd3),
    commands.MakeCmdGroup("bar", cmd1, cmd4).AddConstraint(cmd1, cmd4),
}

出于 80 列长度的原因,我想将我的链分成几行,但 Go 不会让我编译这个:

var cmdGroups = []*commands.CmdGroup {
    commands.MakeCmdGroup("foo", cmd1, cmd2, cmd3)
            .AddConstraint(cmd1, cmd2)
            .AddConstraint(cmd2, cmd1, cmd3),
    commands.MakeCmdGroup("bar", cmd1, cmd4)
            .AddConstraint(cmd1, cmd4),
}

我能做些什么 ?

4

2 回答 2

9

正如 FUZxxl 指出的那样,您的问题是分号的自动插入。规范说:

当输入被分解为标记时,如果该行的最终标记为

  • 标识符
  • 整数、浮点数、虚数、符文或字符串文字
  • 关键字 break、continue、fallthrough 或 return 之一
  • 运算符和分隔符之一 ++、-、)、] 或 }

你有一个函数调用,它算作 a ),所以在行尾添加了一个分号。

要规避自动分号转换,您可以通过以下方式之一编写调用:

使用.代替分号:

x.
Method(p1,p2,p3)

在参数列表的开头而不是函数之前中断:

x.Method(
   p1,p2,p3, // , at the end is important to prevent semicolon insertion
)

如果您不喜欢上述方法,您可以(从 go1.1 开始)将这些方法视为一等公民并临时创建可能更短的快捷方式:

f = x.Method
f(p1,p2,p3).f(p3,p4,p5)

这个例子我想得还不够。f(...).f(...)当然不可能,因为f没有 member的返回值f。一将不得不重新分配f。所以你没有从中得到任何好处。

于 2013-04-17T20:28:12.040 回答
1

我可能会写一些变体:

var cmdGroups = []*commands.CmdGroup{
                commands.MakeCmdGroup(
                        "foo", cmd1, cmd2, cmd3,
                ).AddConstraint(
                        cmd1, cmd2,
                ).AddConstraint(
                        cmd2, cmd1, cmd3,
                ),
                commands.MakeCmdGroup(
                        "bar", cmd1, cmd4,
                ).AddConstraint(cmd1, cmd4),
}

然而,如此长的选择器操作符链在惯用代码中并不常见。(我认为标准库是惯用代码的非正式指南)。也许这种代码设计/结构可能存在一些弱点。

于 2013-04-17T20:25:58.293 回答