0

I would like to know why there is no warning or error in the following code which allows me to override a global variable.

// You can edit this code!
// Click here and start typing.
package main

import "fmt"

type MyStruct struct {
    MyInt uint32
}

func (s *MyStruct) MyMethod() {
    fmt.Println(s.MyInt)
}

var theStruct MyStruct

func main() {

    // Override the above global variable
    // I would expect some kind of warning or error here?
    theStruct := MyStruct {
        MyInt: 42,
    }

    // Outputs 42
    theStruct.MyMethod()

    // Outputs 0
    UseMyStruct()
}

func UseMyStruct() {
    theStruct.MyMethod()
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
rhughes
  • 9,257
  • 11
  • 59
  • 87

1 Answers1

2

Variables are allowed to shadow other variables in parent scopes. In your example, the scope hierarchy looks like this:

global (scope)
├── theStruct (variable)
└── main (scope)
    └── theStruct (variable)

Shadowing like this is often done with err:

package main

import (
    "io/ioutil"
    "log"
)

func main() {
    f, err := ioutil.TempFile("", "")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    // This err shadows the one above, it is technically in its
    // own scope within the "if".
    if _, err := f.Write([]byte("hello world\n")); err != nil {
        log.Fatal(err)
    }

    if true {
        // We can even shadow with different types!
        err := 3

        log.Println(err)
    }
}

This example is in part from "Scope and Shadowing in Go".

Jack Wilsdon
  • 6,706
  • 11
  • 44
  • 87
  • I just had a case where the link was broken in several placrs but, because I had the article title, I could find it elsewhere. – peterSO Oct 02 '19 at 12:25