/**
* 生成系統流水号異常
*/
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語言簡潔和可維護的設計理念。