Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do you chain commands on several lines in go?

Tags:

go

chaining

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 ?

like image 618
Fabien Avatar asked Dec 27 '22 05:12

Fabien


2 Answers

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
)

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)

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.

like image 124
nemo Avatar answered Jan 06 '23 01:01

nemo


I would probably write some variant of:

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

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.

like image 38
zzzz Avatar answered Jan 06 '23 01:01

zzzz