hotime/docs/Common_工具类使用说明.md
hoteas 8dac2aff66 docs(guides): 完善框架文档并新增代码生成器说明
- 添加代码生成器完整使用说明文档,包含配置规则和自定义规则
- 新增 Common 工具类使用说明,介绍 Map/Slice/Obj 类型及转换函数
- 更新 QUICKSTART 文档中的配置项说明和数据库配置示例
- 完善请求参数获取方法,添加新版链式调用推荐用法
- 更新响应数据处理说明,包含错误码含义和自定义响应方法
- 优化中间件和 Session 操作的代码示例
- 修正路由路径参数获取的安全检查逻辑
- 更新 README 添加新文档链接索引
2026-01-22 22:13:05 +08:00

9.7 KiB
Raw Permalink Blame History

HoTime Common 工具类使用说明

common 包提供了 HoTime 框架的核心数据类型和工具函数,包括 MapSliceObj 类型及丰富的类型转换函数。

目录


核心数据类型

Map 类型

Mapmap[string]interface{} 的别名,提供了丰富的链式调用方法。

import . "code.hoteas.com/golang/hotime/common"

// 创建 Map
data := Map{
    "name":   "张三",
    "age":    25,
    "score":  98.5,
    "active": true,
    "tags":   Slice{"Go", "Web"},
}

获取值方法

// 获取字符串
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{}

向上取整方法

// 向上取整获取整数
ceilInt := data.GetCeilInt("score")      // 99
ceilInt64 := data.GetCeilInt64("score")  // int64(99)
ceilFloat := data.GetCeilFloat64("score") // 99.0

操作方法

// 添加/修改值
data.Put("email", "test@example.com")

// 删除值
data.Delete("email")

// 转换为 JSON 字符串
jsonStr := data.ToJsonString()

// 从 JSON 字符串解析
data.JsonToMap(`{"key": "value"}`)

有序遍历

// 按 key 字母顺序遍历
data.RangeSort(func(k string, v interface{}) bool {
    fmt.Printf("%s: %v\n", k, v)
    return false // 返回 true 则终止遍历
})

转换为结构体

type User struct {
    Name  string
    Age   int64
    Score float64
}

var user User
data.ToStruct(&user) // 传入指针,字段名首字母大写匹配

Slice 类型

Slice[]interface{} 的别名,提供类似 Map 的链式调用方法。

// 创建 Slice
list := Slice{
    Map{"id": 1, "name": "Alice"},
    Map{"id": 2, "name": "Bob"},
    "text",
    123,
}

获取值方法

// 按索引获取值(类型转换)
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

向上取整方法

ceilInt := list.GetCeilInt(3)
ceilInt64 := list.GetCeilInt64(3)
ceilFloat := list.GetCeilFloat64(3)

操作方法

// 修改指定位置的值
list.Put(0, "new value")

// 转换为 JSON 字符串
jsonStr := list.ToJsonString()

Obj 类型

Obj 是一个通用的对象包装器,用于链式类型转换,常用于 Context 方法的返回值。

type Obj struct {
    Data interface{} // 原始数据
    Error           // 错误信息
}

使用示例

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 中的应用

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 包提供了一系列全局类型转换函数。

基础转换

// 转字符串
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

向上取整转换

// 向上取整后转整数
ceil := ObjToCeilInt(3.2)     // 4
ceil64 := ObjToCeilInt64(3.2) // int64(4)
ceilF := ObjToCeilFloat64(3.2) // 4.0

时间转换

// 自动识别多种格式
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 微秒

字符串转换

// 字符串转 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,"

错误处理

所有转换函数支持可选的错误参数:

var e Error
i := ObjToInt("abc", &e)
if e.GetError() != nil {
    // 处理转换错误
}

工具函数

字符串处理

// 字符串截取(支持中文)
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 (忽略大小写)

时间处理

// 时间转字符串
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"

加密与随机

// MD5 加密
hash := Md5("password")            // 32位小写MD5

// 随机数
r := Rand(3)                       // 3位随机数 (0-999)
r := RandX(10, 100)                // 10-100之间的随机数

数学计算

// 四舍五入保留小数
f := Round(3.14159, 2)             // 3.14
f := Round(3.145, 2)               // 3.15

深拷贝

// 深拷贝 Map/Slice递归复制
original := Map{"a": Map{"b": 1}}
copied := DeepCopyMap(original).(Map)

// 修改副本不影响原始数据
copied.GetMap("a")["b"] = 2
// original["a"]["b"] 仍然是 1

错误处理

Error 类型

type Error struct {
    Logger *logrus.Logger  // 可选的日志记录器
    error                  // 内嵌错误
}

使用示例

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"))

在类型转换中使用

var e Error
data := Map{"count": "abc"}

count := data.GetInt("count", &e)
if e.GetError() != nil {
    // 转换失败count = 0
    fmt.Println("转换失败:", e.GetError())
}

最佳实践

1. 链式调用处理请求数据

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. 安全的类型转换

// 带错误检查的转换
var e Error
data := someMap.GetInt("key", &e)
if e.GetError() != nil {
    // 使用默认值
    data = 0
}

// 简单场景直接转换(失败返回零值)
data := someMap.GetInt("key")  // 失败返回 0

3. 处理数据库查询结果

// 查询返回 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"))
}

相关文档