天天看點

使用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語言