# HoTime Common 工具类使用说明 `common` 包提供了 HoTime 框架的核心数据类型和工具函数,包括 `Map`、`Slice`、`Obj` 类型及丰富的类型转换函数。 ## 目录 - [核心数据类型](#核心数据类型) - [Map 类型](#map-类型) - [Slice 类型](#slice-类型) - [Obj 类型](#obj-类型) - [类型转换函数](#类型转换函数) - [工具函数](#工具函数) - [错误处理](#错误处理) --- ## 核心数据类型 ### Map 类型 `Map` 是 `map[string]interface{}` 的别名,提供了丰富的链式调用方法。 ```go import . "code.hoteas.com/golang/hotime/common" // 创建 Map data := Map{ "name": "张三", "age": 25, "score": 98.5, "active": true, "tags": Slice{"Go", "Web"}, } ``` #### 获取值方法 ```go // 获取字符串 name := data.GetString("name") // "张三" // 获取整数 age := data.GetInt("age") // 25 age64 := data.GetInt64("age") // int64(25) // 获取浮点数 score := data.GetFloat64("score") // 98.5 // 获取布尔值 active := data.GetBool("active") // true // 获取嵌套 Map info := data.GetMap("info") // 返回 Map 类型 // 获取 Slice tags := data.GetSlice("tags") // 返回 Slice 类型 // 获取时间 createTime := data.GetTime("create_time") // 返回 *time.Time // 获取原始值 raw := data.Get("name") // interface{} ``` #### 向上取整方法 ```go // 向上取整获取整数 ceilInt := data.GetCeilInt("score") // 99 ceilInt64 := data.GetCeilInt64("score") // int64(99) ceilFloat := data.GetCeilFloat64("score") // 99.0 ``` #### 操作方法 ```go // 添加/修改值 data.Put("email", "test@example.com") // 删除值 data.Delete("email") // 转换为 JSON 字符串 jsonStr := data.ToJsonString() // 从 JSON 字符串解析 data.JsonToMap(`{"key": "value"}`) ``` #### 有序遍历 ```go // 按 key 字母顺序遍历 data.RangeSort(func(k string, v interface{}) bool { fmt.Printf("%s: %v\n", k, v) return false // 返回 true 则终止遍历 }) ``` #### 转换为结构体 ```go type User struct { Name string Age int64 Score float64 } var user User data.ToStruct(&user) // 传入指针,字段名首字母大写匹配 ``` --- ### Slice 类型 `Slice` 是 `[]interface{}` 的别名,提供类似 Map 的链式调用方法。 ```go // 创建 Slice list := Slice{ Map{"id": 1, "name": "Alice"}, Map{"id": 2, "name": "Bob"}, "text", 123, } ``` #### 获取值方法 ```go // 按索引获取值(类型转换) str := list.GetString(2) // "text" num := list.GetInt(3) // 123 num64 := list.GetInt64(3) // int64(123) f := list.GetFloat64(3) // 123.0 b := list.GetBool(3) // true (非0为true) // 获取嵌套类型 item := list.GetMap(0) // Map{"id": 1, "name": "Alice"} subList := list.GetSlice(0) // 尝试转换为 Slice // 获取原始值 raw := list.Get(0) // interface{} // 获取时间 t := list.GetTime(0) // *time.Time ``` #### 向上取整方法 ```go ceilInt := list.GetCeilInt(3) ceilInt64 := list.GetCeilInt64(3) ceilFloat := list.GetCeilFloat64(3) ``` #### 操作方法 ```go // 修改指定位置的值 list.Put(0, "new value") // 转换为 JSON 字符串 jsonStr := list.ToJsonString() ``` --- ### Obj 类型 `Obj` 是一个通用的对象包装器,用于链式类型转换,常用于 `Context` 方法的返回值。 ```go type Obj struct { Data interface{} // 原始数据 Error // 错误信息 } ``` #### 使用示例 ```go obj := &Obj{Data: "123"} // 链式类型转换 i := obj.ToInt() // 123 i64 := obj.ToInt64() // int64(123) f := obj.ToFloat64() // 123.0 s := obj.ToStr() // "123" b := obj.ToBool() // true // 复杂类型转换 m := obj.ToMap() // 尝试转换为 Map sl := obj.ToSlice() // 尝试转换为 Slice arr := obj.ToMapArray() // 转换为 []Map // 获取原始值 raw := obj.ToObj() // interface{} // 获取时间 t := obj.ToTime() // *time.Time // 向上取整 ceil := obj.ToCeilInt() ceil64 := obj.ToCeilInt64() ceilF := obj.ToCeilFloat64() ``` #### 在 Context 中的应用 ```go func handler(that *Context) { // ReqData 返回 *Obj,支持链式调用 userId := that.ReqData("user_id").ToInt() name := that.ReqData("name").ToStr() // Session 也返回 *Obj adminId := that.Session("admin_id").ToInt64() } ``` --- ## 类型转换函数 `common` 包提供了一系列全局类型转换函数。 ### 基础转换 ```go // 转字符串 str := ObjToStr(123) // "123" str := ObjToStr(3.14) // "3.14" str := ObjToStr(Map{"a": 1}) // JSON 格式字符串 // 转整数 i := ObjToInt("123") // 123 i64 := ObjToInt64("123") // int64(123) // 转浮点数 f := ObjToFloat64("3.14") // 3.14 // 转布尔 b := ObjToBool(1) // true b := ObjToBool(0) // false // 转 Map m := ObjToMap(`{"a": 1}`) // Map{"a": 1} m := ObjToMap(someStruct) // 结构体转 Map // 转 Slice s := ObjToSlice(`[1, 2, 3]`) // Slice{1, 2, 3} // 转 []Map arr := ObjToMapArray(slice) // []Map ``` ### 向上取整转换 ```go // 向上取整后转整数 ceil := ObjToCeilInt(3.2) // 4 ceil64 := ObjToCeilInt64(3.2) // int64(4) ceilF := ObjToCeilFloat64(3.2) // 4.0 ``` ### 时间转换 ```go // 自动识别多种格式 t := ObjToTime("2024-01-15 10:30:00") // *time.Time t := ObjToTime("2024-01-15") // *time.Time t := ObjToTime(1705298400) // Unix 秒 t := ObjToTime(1705298400000) // Unix 毫秒 t := ObjToTime(1705298400000000) // Unix 微秒 ``` ### 字符串转换 ```go // 字符串转 Map m := StrToMap(`{"key": "value"}`) // 字符串转 Slice s := StrToSlice(`[1, 2, 3]`) // 字符串转 int i, err := StrToInt("123") // 字符串数组格式转换 jsonArr := StrArrayToJsonStr("a1,a2,a3") // "[a1,a2,a3]" strArr := JsonStrToStrArray("[a1,a2,a3]") // ",a1,a2,a3," ``` ### 错误处理 所有转换函数支持可选的错误参数: ```go var e Error i := ObjToInt("abc", &e) if e.GetError() != nil { // 处理转换错误 } ``` --- ## 工具函数 ### 字符串处理 ```go // 字符串截取(支持中文) str := Substr("Hello世界", 0, 7) // "Hello世" str := Substr("Hello", -2, 2) // "lo" (负数从末尾计算) // 首字母大写 upper := StrFirstToUpper("hello") // "Hello" // 查找最后出现位置 idx := IndexLastStr("a.b.c", ".") // 3 // 字符串相似度(Levenshtein 距离) dist := StrLd("hello", "hallo", true) // 1 (忽略大小写) ``` ### 时间处理 ```go // 时间转字符串 str := Time2Str(time.Now()) // "2024-01-15 10:30:00" str := Time2Str(time.Now(), 1) // "2024-01" str := Time2Str(time.Now(), 2) // "2024-01-15" str := Time2Str(time.Now(), 3) // "2024-01-15 10" str := Time2Str(time.Now(), 4) // "2024-01-15 10:30" str := Time2Str(time.Now(), 5) // "2024-01-15 10:30:00" // 特殊格式 str := Time2Str(time.Now(), 12) // "01-15" str := Time2Str(time.Now(), 14) // "01-15 10:30" str := Time2Str(time.Now(), 34) // "10:30" str := Time2Str(time.Now(), 35) // "10:30:00" ``` ### 加密与随机 ```go // MD5 加密 hash := Md5("password") // 32位小写MD5 // 随机数 r := Rand(3) // 3位随机数 (0-999) r := RandX(10, 100) // 10-100之间的随机数 ``` ### 数学计算 ```go // 四舍五入保留小数 f := Round(3.14159, 2) // 3.14 f := Round(3.145, 2) // 3.15 ``` ### 深拷贝 ```go // 深拷贝 Map/Slice(递归复制) original := Map{"a": Map{"b": 1}} copied := DeepCopyMap(original).(Map) // 修改副本不影响原始数据 copied.GetMap("a")["b"] = 2 // original["a"]["b"] 仍然是 1 ``` --- ## 错误处理 ### Error 类型 ```go type Error struct { Logger *logrus.Logger // 可选的日志记录器 error // 内嵌错误 } ``` ### 使用示例 ```go var e Error // 设置错误 e.SetError(errors.New("something wrong")) // 获取错误 if err := e.GetError(); err != nil { fmt.Println(err) } // 配合日志自动记录 e.Logger = logrusLogger e.SetError(errors.New("will be logged")) ``` ### 在类型转换中使用 ```go var e Error data := Map{"count": "abc"} count := data.GetInt("count", &e) if e.GetError() != nil { // 转换失败,count = 0 fmt.Println("转换失败:", e.GetError()) } ``` --- ## 最佳实践 ### 1. 链式调用处理请求数据 ```go func handler(that *Context) { // 推荐:使用 Obj 链式调用 userId := that.ReqData("user_id").ToInt() page := that.ReqData("page").ToInt() if page < 1 { page = 1 } // 处理 Map 数据 user := that.Db.Get("user", "*", Map{"id": userId}) if user != nil { name := user.GetString("name") age := user.GetInt("age") } } ``` ### 2. 安全的类型转换 ```go // 带错误检查的转换 var e Error data := someMap.GetInt("key", &e) if e.GetError() != nil { // 使用默认值 data = 0 } // 简单场景直接转换(失败返回零值) data := someMap.GetInt("key") // 失败返回 0 ``` ### 3. 处理数据库查询结果 ```go // 查询返回 Map user := that.Db.Get("user", "*", Map{"id": 1}) if user != nil { name := user.GetString("name") createTime := user.GetTime("create_time") } // 查询返回 []Map users := that.Db.Select("user", "*", Map{"status": 1}) for _, u := range users { fmt.Printf("ID: %d, Name: %s\n", u.GetInt("id"), u.GetString("name")) } ``` --- ## 相关文档 - [快速上手指南](QUICKSTART.md) - [HoTimeDB 使用说明](HoTimeDB_使用说明.md) - [代码生成器使用说明](CodeGen_使用说明.md)