Can't access global variable declared in main

I am writing an app that is using spf13/cobra for command line processing. Pardon my noobness, my 4th week writing Go. I’ve seen other posts like this but for some reason not working for me. Doing something wrong here.

My directory structure is as follows:

myapp/cmd/myapp
    main.go
    types.go
    <other files>
myapp/cmd/myapp/cli
    root.go
    <various other command files>

My pseudo code:

// main.go:
package main

import myapp/cmd/myapp/cli

var  Cfg *MyStruct

func main() {
    Cfg = &MyStruct{}
}

// cli/root.go:
package cli

func init() {
    rootCmd.PersistentFlags().StringVarP(
        &Cfg.Options.Endpoint,
        "blah",
        "",
        "",
        "")
}

It complains that Cfg is undefined.

Thanks for any help.

If the variable is in package main should it be accessed with main.Cfg however the init routine of cli is run before main() so the variable will be nil at that point. Instead of using a init function could you have a function which initialises cli and give Cfg as an argument to this function.

So is cli.init() called when the package is first imported somewhere?

Also what other way would I initialize cli, I thought that is what init() was for?

All imported packages init functions are called before main. You could just make a function called setup, initialize, config etc and call it from main.

Ok I’m confused. I just tried every possible permutation of creating sub directories, new packages, init() functions, setup() functions and every time I hit a roadblock.

If I create a sub-directory called “setup” with setup.go, then try and return my MyStruct type, it’s not defined in the package setup… if I fix that, then the problem is elsewhere.

What exactly do I need to do to get a struct variable visible to EVERYTHING in my compile binary, regardless of what package or sub-directory it’s in.

Man almost just wanna go back to writing C.

You need to include the package and then use that.

If your package is called example.com/foo and you have a variable Bar in there you can use it after importing the package like foo.Bar. Types and functions are similar to use.

But this is in main and can’t be imported.

Then you need to redesign and move that variable into another package.

Create a package “config” with the exported variable Cfg. Then import package “config” into package “main” and set the value for ‘config.Cfg’. Import package “config” into package “cli” and use the value of ‘config.Cfg’.

2 Likes

I ended up doing something like that with the combination of a constructor function wrapper around my struct and a config package.

Thx for the help.

1 Like