Search code examples
gouser-interfacefyne

Assigning proper value from for loop in GUIs


I have been learning the Fyne library for making GUIs in Go, and have run into a problem.

func createResponses(content *fyne.Container){
for i:=0;i<address.childrenCount;i++{
    content.Add(widget.NewButton(address.children[i].text,func(){
        fmt.Println(i)
    }))
}}

This is supposed to iterate through the children of a node, add a button with the text stored in that node, and then when clicked, print the value of i when it was created to the console. However, while the text of the button, the first parameter (address.children[i].text), displays correctly, the value of i always prints out the same, as 3, the number that causes the loop to terminate.

At first I though this was a specific problem to Fyne, or my poor understanding of how to use Go in general, but I recall having a similar problem when I first learned JavaFX. Is there something about GUIs that causes this behavior to emerge? More importantly, what is the proper way of dealing with this problem? Thank you!


Solution

  • This is to do with using a delayed function inside the for loop. By the time the code executed the i variable will be at the last value. Solution is to “capture” the value before passing it to the callback.

    for i:=0;i<address.childrenCount;i++{
        index := i
        content.Add(widget.NewButton(address.children[i].text,func(){
            fmt.Println(index)
        }))
    }