有没有一种方法可以在Go语言中反映一个包的所有变量?

huangapple go评论78阅读模式
英文:

Is there a way to reflect all variables of one package in go?

问题

我在一个包中定义了一些全局变量,它们是一个名为"exception"的包中用户自定义结构体的类型。(Go语言不支持结构体的常量,所以我使用了变量)

var (
	ErrorCodeSuccess = Error{Code: 0, ErrDetail: "success"} // 
)

var (
	ACodeDefault                        = Error{Code: 10000, ErrDetail: "detail1"}    
	ACodeInValidParams                  = Error{Code: 10100, ErrDetail: "detail2"}    
)

var(
   BCodeDefault....// 等等
)

var(
   CCodeDefault....// 等等
)

如你所见,Error的一个实例定义了一个错误代码以及它的默认详细信息。

但是当用户真正想要指定详细信息时,用户可以像这样更改它:

ACodeDefault.ReNew("更具体的细节").

这个方法将返回一个带有新详细信息的Error的副本。

这里是我的问题,用户指定的详细信息可能有很多。

例如,当用户返回代码10000时,可能在不同的请求中有100个不同的详细信息。

但有时,我希望默认的详细信息加上代码变成10000-details1,这样我就可以报告给监控系统。

所以我需要一个函数像mapCodeToDefaultDetails(code int)。然后,我希望能够反射所有的变量来构建一个映射(代码->默认详细信息),这样我就可以实现这个方法。

有没有办法实现这个?

英文:

I defined some global variables of error code in one packages.Their types are user-defined structs in a package exception. (Go does not support const of structs so I use var)

var (
	ErrorCodeSuccess = Error{Code: 0, ErrDetail: "success"} // 
)

var (
	ACodeDefault                        = Error{Code: 10000, ErrDetail: "detail1"}    
	ACodeInValidParams                  = Error{Code: 10100, ErrDetail: "detail2"}    
)

var(
   BCodeDefault....// and so on
)

var(
   CCodeDefault....// and so on
)

As you can see, a instance of Error define an error code along with its default detail.

But when user really want to specify its details, user can change it like

ACodeDefault.ReNew("more specify details").

This method will return a copy of this Error with a new detail.

Here is my problem, the user specified details may be many.

For example, when user return code 10000, there may be 100 different details in different requests.

But sometimes, I want the default details along with the code to be like 10000-details1 so that I can report to the monitor systems.

So I need a function like mapCodeToDefaultDetails(code int). Then, I hope I can reflect all the variables to build a map(code-> default detail) so that I can implement this method.

is there any ways to achieve this?

答案1

得分: 1

reflect包没有提供一种列举包中变量的方法。

以下是一种实现该功能的方法:添加一个注册函数,用于将代码的错误详细信息记录在一个映射中:

var codeDetails = map[int]string{}

func register(e Error) Error {
    codeDetails[e.Code] = e.Details
    return e
}

在声明变量时使用注册函数:

var ErrorCodeSuccess = register(Error{Code: 0, ErrDetail: "success"})

mapCodeToDefaultDetails函数中使用映射:

func mapCodeToDefaultDetails(code int) string {
    return codeDetails[code]
}
英文:

The reflect package does not provide a way to enumerate the variables in a package.

Here's one way to implement the feature: Add a registration function to record the error detail for a code in a map:

var codeDetails = map[int]string{}

func register(e Error) Error {
    codeDetails[e.Code] = e.Details
    return e
}

Use the registration function when declaring the variables:

var ErrorCodeSuccess = register(Error{Code: 0, ErrDetail: "success"})

Use the map in mapCodeToDefaultDetails:

 func mapCodeToDefaultDetails(int code) string {
      return codeDetails[code]
 }

huangapple
  • 本文由 发表于 2022年3月22日 11:06:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/71566484.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定