天天看点

使用Claude帮我把Java枚举类转Go语言

作者:程序员阿辉
使用Claude帮我把Java枚举类转Go语言
/**
 * 生成系统流水号异常
 */
USER_CODE_ERROR("100003", "用户短号配置错误:%s"),

/**
 * 参数格式必须为json
 */
PARAM_VALID_JSON_ERROR("100004", "参数格式必须为json"),

/**
 * 配置错误
 */
CONFIG_EXIST_MANY_ERROR("100008", "存在多个配置文件,appId不能为空"),

/**
 * 初始化错误
 */
CONFIG_NOT_INIT_ERROR("100010", "配置文件未加载,请调用init方法进行初始化加载配置文件"),
/**
 * 初始化错误
 */
HD_CONFIG_NOT_INIT_ERROR("100010", "回单配置文件未加载,请调用init方法进行初始化加载配置文件"),           

现在有好几十个Java枚举代码需要转Go

Claude应用 晚上 8:39

这几个异常码和消息的Go语言实现:

const (
    USER_CODE_ERROR                  = "100003"  
    USER_CODE_ERROR_MSG              = "用户短号配置错误:%s"

    PARAM_VALID_JSON_ERROR         = "100004"  
    PARAM_VALID_JSON_ERROR_MSG     = "参数格式必须为json"  

    CONFIG_EXIST_MANY_ERROR        = "100008"
    CONFIG_EXIST_MANY_ERROR_MSG    = "存在多个配置文件,appId不能为空"

    CONFIG_NOT_INIT_ERROR          = "100010" 
    CONFIG_NOT_INIT_ERROR_MSG      = "配置文件未加载,请调用init方法进行初始化加载配置文件"

    HD_CONFIG_NOT_INIT_ERROR       = "100010"  
    HD_CONFIG_NOT_INIT_ERROR_MSG   = "回单配置文件未加载,请调用init方法进行初始化加载配置文件"
)

var ExceptionMap = map[string]string{
    USER_CODE_ERROR:   USER_CODE_ERROR_MSG,
    PARAM_VALID_JSON_ERROR: PARAM_VALID_JSON_ERROR_MSG,  
    CONFIG_EXIST_MANY_ERROR:  CONFIG_EXIST_MANY_ERROR_MSG,
    CONFIG_NOT_INIT_ERROR: CONFIG_NOT_INIT_ERROR_MSG,
    HD_CONFIG_NOT_INIT_ERROR: HD_CONFIG_NOT_INIT_ERROR_MSG, 
}
           

使用:

errCode := USER_CODE_ERROR
errMsg := ExceptionMap[errCode]
fmt.Printf("errCode: %s, errMsg: %s", errCode, errMsg)
// 输出:
// errCode: 100003, errMsg: 用户短号配置错误:%s
           

对这几个异常信息,直接定义相应的常量和在map中绑定即可。

代码比较简洁,但同时也具备异常信息的灵活定义特性。

而如果用Java的枚举类来定义,可能会比较繁琐,尤其是有多个相同异常码的情况,不如Go语言的map这样可以灵活绑定多个消息。

所以,总体来说,对这些异常信息的定义,使用Go语言的常量和map的方式是一个很好的选择。简洁高效,且不失灵活性。这也就是Go语言设计的精髓之一。

阿辉 晚上 8:44

map满足不了重复的key

Claude应用 晚上 8:44

你说的对,Go语言的map不支持重复的key。对于这个场景,如果有多个相同的异常码,但异常消息不同,map就无法直接映射。可以有几种解决方案:1. 使用slice代替map。可以定义一个结构体:

go
type Exception struct {
    Code string
    Msg  string 
}

var Exceptions []Exception = []Exception{
    {Code: "100003", Msg: "用户短号配置错误:%s"},
    {Code: "100003", Msg: "其他消息"}, 
    // ...
}
           

然后通过异常码在slice中查找对应消息。这种方式支持重复key,但查找效率会略低于map。2. 为相同异常码定义多个常量:

go
const (
    USER_CODE_ERROR_1   = "100003"  
    USER_CODE_ERROR_MSG_1 = "用户短号配置错误:%s"

    USER_CODE_ERROR_2   = "100003"  
    USER_CODE_ERROR_MSG_2 = "其他消息"
)

var ExceptionMap = map[string]string{
    USER_CODE_ERROR_1:   USER_CODE_ERROR_MSG_1,
    USER_CODE_ERROR_2:   USER_CODE_ERROR_MSG_2, 
}
           

这种方式可以在map中正常映射,但异常码不再是统一的值,不太优雅。3. 为相同异常码定义一个结构体:

go
type UserCodeError struct {
    Code   string
    Msg1   string
    Msg2   string
}

var USER_CODE_ERROR = UserCodeError{"100003", "用户短号配置错误:%s", "其他消息"}

var ExceptionMap = map[string]interface{}{
    "100003": USER_CODE_ERROR, 
}
           

然后可以通过`exceptionMsg := ExceptionMap["100003"].(UserCodeError)`获取该结构体,并选择需要的消息。

这种方式异常码仍是统一值,且可以在map中映射,比较符合要求。当然,查找和类型断言会略微繁琐一些。

所以,对于Go语言map不支持重复key的场景,可以选择使用slice代替,或为相同key定义多个常量映射,又或使用结构体来绑定多个消息。

这几种方式都有各自的优点,可以根据具体场景选择。对这个例子,我会推荐第3种方式,定义一个结构体绑定多个消息,这比较符合异常信息的定义方式,同时可以很好地解决map的key重复限制问题。

当然,也可以根据实际需求,选择其他方式。Go语言虽然在某些方面有一定限制,但其灵活的类型系统和丰富的内建类型,也为解决这些限制提供了很好的支持。

熟练使用Go语言的类型系统是编写高质量代码的关键。

阿辉 晚上 8:48

转成这种形式

type SDKError struct {
   Code    string
   Message string
}

var    CONFIG_PATH_ERROR = SDKError{"100000", "没有找到配置文件:%s"}           

Claude应用 晚上 8:48

可以像这样定义这些异常信息:

go
type SDKError struct {
   Code    string
   Message string 
}

var CONFIG_PATH_ERROR = SDKError{"100000", "没有找到配置文件:%s"}
var CONFIG_NULL_ERROR = SDKError{"100002", "初始化参数为空 ,请检查配置文件"}
var USER_CODE_ERROR = SDKError{"100003",  "用户短号配置错误:%s"} 
var PARAM_VALID_JSON_ERROR = SDKError{"100004", "参数格式必须为json"}

var CONFIG_EXIST_MANY_ERROR = SDKError{"100008", "存在多个配置文件,appId不能为空"}
var CONFIG_NOT_INIT_ERROR = SDKError{"100010", "配置文件未加载,请调用init方法进行初始化加载配置文件"} 
var HD_CONFIG_NOT_INIT_ERROR = SDKError{"100010","回单配置文件未加载,请调用init方法进行初始化加载配置文件"}
           

然后在程序中可以这么使用:

go
err := CONFIG_PATH_ERROR 
fmt.Printf("err.Code: %s, err.Message: %s", err.Code, err.Message)
// 输出: 
// err.Code: 100000, err.Message: 没有找到配置文件:%s
           

这种结构体方式的主要优点是:

1. 异常码和消息维护一个对应关系,类似Java的枚举。

2. 可以包含更丰富的异常信息,不仅仅是消息,还可以有其他字段。

3. 修改消息时,直接修改结构体字段值即可,无需在map中同步更改。

4. 可以支持相同异常码的不同消息,通过定义多个结构体实例来映射。

但是,也有一定缺点:

1. 访问异常信息时,需要先获取具体的结构体实例,然后才可以访问消息内容,不如map直接访问消息那么简便。

2. 如果有大量异常信息,定义大量结构体实例会显得比较冗长和繁琐。

所以,这种结构体方式在以下场景更加适用:

1. 异常信息不太多,但需要包含更丰富的内容,不仅仅是简单的消息。

2. 异常消息可能有重复的异常码,或未来可能会有变化。

3. 需要在异常码和消息之间建立比较固定的对应关系。

如果仅是大量简单的异常码和消息,Map方式可能更加清晰和简便。

对这个例子,异常信息不太复杂,主要是异常码和对应的消息,所以Map方式也是一个好的选择。但使用结构体也同样可以满足需求,并且带来异常信息定义更加规范的好处。

所以,对这个例子,我会推荐使用结构体的方式来定义这些异常信息。它可以带来代码的整洁性和可维护性,比Map略高一筹,这在项目长期维护阶段会有更大的价值。当然,如果异常信息量级非常大,为了简便也可以选择Map方式。需要根据具体场景权衡,选择最适合的方式。

但总体来说,在Go语言中使用结构体来定义域相关信息是一个很好的实践,这也符合Go语言简洁和可维护的设计理念。

使用Claude帮我把Java枚举类转Go语言
使用Claude帮我把Java枚举类转Go语言