如何在Go语言中将多个命令链接在几行上?

huangapple go评论82阅读模式
英文:

how do you chain commands on several lines in 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),
}

出于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),
}

我该怎么办?

英文:

I want to chain commands this way :

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),
}

I'd like to split my chains on several lines for 80-column-lengths reasons, but Go won't let me compile this :

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),
}

what can I do ?

答案1

得分: 14

如FUZxxl所指出的,你的问题是自动插入分号。
规范说:

当输入被分解为标记时,如果行的最后一个标记是

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

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

为了避免自动分号转换,你可以按照以下方式编写你的调用:

使用.代替分号:

x.
Method(p1,p2,p3)

在参数列表开始之后而不是函数之前换行:

x.Method(
   p1,p2,p3, // 在末尾的逗号是为了防止分号插入
)

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

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

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

英文:

As FUZxxl pointed out, your problem is the automatic insertion of semicolons.
The spec says:

> When the input is broken into tokens, a semicolon is automatically
> inserted into the token stream at the end of a non-blank line if the
> line's final token is
>
> - an identifier
> - an integer, floating-point, imaginary, rune, or string
> literal
> - one of the keywords break, continue, fallthrough, or return
> - one of the operators and delimiters ++, --, ), ], or }

You have a function call, which counts for a ) so a semicolon is added at the end of the line.

To circumvent automatic semicolon conversion you can write your calls in one of the following
ways:

Use the . instead of semicolon:

x.
Method(p1,p2,p3)

Break after beginning of parameter list instead of before the function:

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

<strike>If you dislike the methods above, you can (as of go1.1) treat the methods as first class
citizens and temporarily create shortcuts which might be shorter:

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

</strike> I haven't thought enough
with this example. f(...).f(...) is of course not possible, as the return value of f has no member f.
One would have to reassign f. So you gain nothing from that.

答案2

得分: 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),
}

然而,在惯用代码中很少见到这样的长选择器操作链。(我认为标准库是惯用代码的非正式指南)。也许这段代码设计/结构上存在一些弱点。

英文:

I would probably write some variant of:

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

However, such long selector operator chains are not to be seen in idiomatic code too often. (I consider the standard library an informal guide to idiomatic code). Perhaps there might be some weakness in this code design/structure.

huangapple
  • 本文由 发表于 2013年4月18日 04:16:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/16069442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定