Get variable/const names dinamycally


(Edjan Michiles) #1

Hey, guys. I’m looking for a way to get my variable names dinamically in the code, I found the stringer tool https://github.com/golang/tools/blob/master/cmd/stringer/stringer.go but think that is a big overhead (compile and generate specific files) to do a simple task.

I think that can be a great ideia have something like that in the reflect package.
Ex: fmt.Println(reflect.NameOf(myVar))

Someone know if is it possible?


(Sean Killian) #2

Unauthoritative answer: It can’t be done, but I’m curious what your use case is.


(Edjan Michiles) #3

I have some consts representing resources:

type Resource int32

const (
	ResourceCustomerLoyalty       Resource = 0
	ResourceOverallVisitsShare    Resource = 1
	ResourceMostVisitedCategories Resource = 2
)

I also have a frontend that send requests for these resourcers. When I don’t find one of this, I want to say “ResourceCustomerLoyalty not found”. But if I do fmt.Errorf("%s not found", resources[i]), where resourcers is an array of Resource, I’ll print “0 not found”.

And refactor the consts to be string is out of the league :stuck_out_tongue:


(Norbert Melzer) #4

That’s why you usually implement fmt.Stringer interface for such enumeration constants with a dedicated type.


(Sean Killian) #5

@Edjan_Michiles I see, so it’s not the variable name you want but a string representation of the value. In that case, the stringer tool you referenced is exactly what you’re looking for. Just put:

//go:generate stringer -type Resource

above your Resource type definition and then run go generate once to generate a resource_string.go file with a fmt.Stringer implementation for you. You can check the resulting code; there’s no real overhead. Less than a custom implementation mot of the time.

Edit: typo.


(Ali Koyuncu) #6

If you have that such a few constants, I would write their string representation by myself rather than using a tool.

type Resource int32

const (
	ResourceCustomerLoyalty       Resource = 0
	ResourceOverallVisitsShare    Resource = 1
	ResourceMostVisitedCategories Resource = 2
)

func (res Resource) String() string {
	switch res {
	case ResourceCustomerLoyalty:
		return "ResourceCustomerLoyalty"
	case ResourceOverallVisitsShare:
		return "ResourceOverallVisitsShare"
	case ResourceMostVisitedCategories:
		return "ResourceMostVisitedCategories"
	default:
		return ""
	}
}
func getResource(resourceInt int) (res Resource, valid bool) {
	if resourceInt >= 0 && resourceInt <= 2 {
		return Resource(resourceInt), true
	}
	return Resource(-1), false
}
func main() {
	res, ok := getResource(0)
	if !ok {
		fmt.Printf("unexpected resource:%d", res)
		return
	}
	fmt.Printf("%s is found", res)
}

https://play.golang.org