Home > Blockchain >  Instantiate a package variable using just the name
Instantiate a package variable using just the name

Time:08-09

I am trying to add some simple validation code for some exported types in a package full of constants. I want to walk the package, figure out the exported consts (which are just strings) and verify their format.

Think of it like I have a flags package that exports consts FlagDoAThing = "do-a-thing". I want to walk that package and check out what those values are.


As an example I've got two files:

// main.go
func main() {
    cfg := &packages.Config{
        Mode: packages.NeedTypes,
    }
    pkgs, _ := packages.Load(cfg, "package-inspector/other")
    pkg := pkgs[0]

    scope := pkg.Types.Scope()
    for _, name := range scope.Names() {
        fmt.Println(name)
        obj := scope.Lookup(name)
        fmt.Println(obj)
        fmt.Println("\t", obj.Id(), obj.Type())
    }
}

Then in my other package I have

package other

const (
    ExportedOne = "exported_one"
    ExportedTwo = "exported_two"

    privateOne = "private_one"
)

When running locally (couldn't get the playground to like me) I am seeing

go run main.go
ExportedOne
const package-inspector/other.ExportedOne untyped string
         ExportedOne untyped string
ExportedTwo
const package-inspector/other.ExportedTwo untyped string
         ExportedTwo untyped string

What I'm trying to do is get a handle on the value of ExportedOne.

CodePudding user response:

You can type-assert the object to *types.Const and then access the value through its Val method.

o := s.Lookup(name)
if c, ok := o.(*types.Const); ok {
    fmt.Println(c.Val())
}

See example: https://go.dev/play/p/oXX7Mo897bk

  • Related