0

Here is a working program that declares variables prior to a for-loop.

package main

import "fmt"

type brackets struct {
    ch   string
    pos  int
}

type stack []brackets

func main() {
    p := brackets{ch: "a"}
    st := make(stack,0)
    for i :=  0; i < 3; i++ {
        p = brackets{ch: "a", pos: 1}
        st = append(st, p) 
        fmt.Println(p)
        fmt.Println(st)
    }
}

I want to declare the same variables as part of the for-loop. How? Here is a faulty attempt.

package main

import "fmt"

type brackets struct {
    ch   string
    pos  int
}

type stack []brackets

func main() {
//    p := brackets{ch: "a"}
//    st := make(stack,0)
    for st, p, i :=  make(stack,0), brackets{ch: "a"}, 0; i < 3; i++ {
        p = brackets{ch: "a", pos: 1}
        st = append(st, p) 
        fmt.Println(p)
        fmt.Println(st)
    }
}

I get the following error: syntax error: st, p, i := make(stack, 0), brackets used as value

I am puzzled, as it is very easy to declare standard types such as ints and strings. Why not my struct?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Fred
  • 564
  • 10
  • 21
  • You simply cannot. Go‘s syntax doesn‘t allow this. – Volker Dec 14 '19 at 14:38
  • I've already looked at the Go reference for SimpleStmt but it is unclear. Can you refer or explain why you say 'simply cannot'? Can you refer or give a list of examples? I ask this question because I want clarity on what is allowable and not allowable. – Fred Dec 14 '19 at 14:41

1 Answers1

5

The composite literal section of the specification says:

A parsing ambiguity arises when a composite literal using the TypeName form of the LiteralType appears as an operand between the keyword and the opening brace of the block of an "if", "for", or "switch" statement, and the composite literal is not enclosed in parentheses, square brackets, or curly braces. In this rare case, the opening brace of the literal is erroneously parsed as the one introducing the block of statements. To resolve the ambiguity, the composite literal must appear within parentheses.

Fix the code by adding parentheses around the composite literal:

for st, p, i :=  make(stack,0), (brackets{ch: "a"}), 0; i < 3; i++ {
    p = brackets{ch: "a", pos: 1}
    st = append(st, p) 
    fmt.Println(p)
    fmt.Println(st)
}

Run it on the playground.

Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • 1
    i could not find this, the for statement spec are not mentioning it (or i missed) https://golang.org/ref/spec#For_statements –  Dec 14 '19 at 14:41
  • Cool! All I do is add parentheses. I knew there was a simple solution. Thank you. – Fred Dec 14 '19 at 14:45