handling constant of maps

367 views
Skip to first unread message

Amarjeet Anand

unread,
May 5, 2020, 12:30:13 AM5/5/20
to golang-nuts
Hi

I want to declare a constant that maps an ErrorCode(string) like "100.01" to its ErrorDescription(string) like "Error description of 100.01".
Declaring Error as code and description is helpful to monitor logs based based on ErrorCode and show the ErrorDescription to the client.

Although go cannot create constant of type map, but it can be achieved in multiple ways.

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
One possible way can be :- 


type ErrorCode string

const (
E270_01 ErrorCode = "270.01"
E270_02 = "270.02"
)

var ErrDescription = map[ErrorCode]string{
E270_01: "this is error description",
E270_02: "this is error description",
}

type LogErr struct {
Code ErrorCode
Description string
}

func getLogErr(e ErrorCode) LogErr {
return LogErr{
Code: e,
Description: ErrDescription[e],
}
}

func TestErrorConstant(t *testing.T) {
fmt.Println(getLogErr(E270_01))
}


This solves our purpose. But the problem is for every new error, we need to change things at two places, (1) Declare const like E270_02 (2) Add an entry in the ErrDescription map



-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Another possible way looks like :-


type ErrorCode string

const (
E270_01 ErrorCode = "270.01:this is error description"
E270_02 = "270.02:this is error description"
)

type LogErr struct {
Code string
Description string
}

func getLogErr(e ErrorCode) LogErr {
token := strings.Split(string(e), ":")
return LogErr{
Code: token[0],
Description: token[1],
}
}

func TestErrorConstant(t *testing.T) {
fmt.Println(getLogErr(E270_01))
}


This way looks promising, but don't really like the way of splitting string using ":"



-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

I think best way could have been something like ---

const (
E270_01 ErrorCode = {"270.01", "this is error description"}
)


Since Golang doesn't support the Constant of struct, what could be your approach?

Any suggestion is really appreciated.

Kurtis Rader

unread,
May 5, 2020, 12:45:24 AM5/5/20
to Amarjeet Anand, golang-nuts
See https://blog.golang.org/generate and https://godoc.org/golang.org/x/tools/cmd/stringer for an example of a now standard Go tool that seems to do what you want.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/198455c0-4f81-4e2f-a166-72796a15d498%40googlegroups.com.


--
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank

Amarjeet Anand

unread,
May 5, 2020, 8:22:14 AM5/5/20
to Kurtis Rader, golang-nuts
Hi Kurtis
Thanks for the response.

As the doc says, stringer can be used to generate only int constants. String constants are not supported.
In my case, the constant will be like - 

type ErrCode string
const (
E201_01 ErrCode = "description text"
)


Actually I need both the strings(E201_01 and "description text") accessible in my code.
Is this also achievable using generate/stringer?



Amarjeet Anand

unread,
May 5, 2020, 8:44:01 AM5/5/20
to Kurtis Rader, golang-nuts
Or I will have to go like this?

type ErrCode struct {
Code string
Desc string
}

var (
E100_01 = ErrCode{"E100_01", "this is description"}
E100_02 = ErrCode{"E100_02", "this is description"}
)



Uli Kunitz

unread,
May 5, 2020, 2:49:53 PM5/5/20
to golang-nuts
Hi Amarjeet

If you take the trouble of using error codes you should use actual integers and not strings. The playground program shows how I would do´ it.

Kevin Chowski

unread,
May 6, 2020, 1:38:35 PM5/6/20
to golang-nuts
I would do (and have done) what you suggested in your last example, but just put the codes into a 'var' block as opposed to a const block, e.g.:

var (
   E270_01 = ErrorCode{"270.01", "this is error description"}
)

I would not personally be concerned about people modifying that public value and messing things up because that has never happened within the past 5 years of my professional career using Go (on two different teams, working with a total of up to 30 other people). At least, as far as I know ;)

If you are concerned about future coders misusing these "effectively constant" public values, then you should just use a function to return a new copy each time instead of having a global/shared version:

func E270_01() ErrorCode {
   return ErrorCode{"270.01", "this is error description"}
}

In this func example, each time someone needs an ErrorCode to use or compare to, they will receive a new copy of ErrorCode, making it impossible for misbehaving code to affect other code.

Amarjeet Anand

unread,
May 9, 2020, 6:46:17 AM5/9/20
to Kevin Chowski, golang-nuts
Thanks Kevin for your opinion.
Now am assured that variable way works.
I will use that.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages