Help us shape the future of Go! Take the 2026 Go Developer Survey

helper

package
v1.78.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func BytesToString deprecated

func BytesToString(b []byte) string

BytesToString 以零拷贝方式把 []byte 转为 string。

Deprecated: 使用 infra/bytesconv.BytesToString。本包保留该转发仅为兼容, 新代码请直接引用 infra/bytesconv,以免底层包反向依赖 helper。

Example

Example functions

bytes := []byte("Hello, World!")
str := BytesToString(bytes)
fmt.Println(str)
Output:
Hello, World!

func Chain

func Chain(handlers ...context.Handler) context.Handler

Chain 组合多个 Handler 为一个 Handler

按顺序执行所有 Handler,如果任何一个返回错误,立即停止并返回该错误。

使用场景:

  • 将复杂的业务逻辑分解为多个步骤
  • 复用常见的 Handler 逻辑
  • 保持代码清晰和可维护

示例:

validateInput := func(ctx *context.Context) error {
    // 验证输入
    return nil
}

processData := func(ctx *context.Context) error {
    // 处理数据
    return nil
}

formatOutput := func(ctx *context.Context) error {
    // 格式化输出
    return nil
}

handler := helper.Chain(
    validateInput,
    processData,
    formatOutput,
)

eng.OnCommand("/api").Handle(handler)

错误处理:

  • 如果任何一个 Handler 返回错误,链立即停止
  • 返回第一个遇到的错误

func ChainGeneric

func ChainGeneric[Ctx any](handlers ...func(Ctx) error) func(Ctx) error

ChainGeneric 将多个具有相同签名的函数合并为一个函数。

函数按顺序执行,若任一函数返回错误,链式调用立即停止并返回该错误。

这是泛型版本,适用于任意上下文类型,而非仅限于 *context.Context。 若要对 Remilia 专属的 context.Handler 进行链式调用,请使用 handler.go 中的非泛型 Chain 函数。

示例:

// 用于自定义上下文类型
type MyContext struct { UserID string }
handler := ChainGeneric[*MyContext](
    validateInput,
    parseCommand,
    executeLogic,
)

// 用于 HTTP 上下文
type HTTPContext struct { /* ... */ }
httpHandler := ChainGeneric[*HTTPContext](
    authMiddleware,
    rateLimit,
    businessLogic,
)

性能:

  • 空链或单处理器链零分配
  • 多处理器链极低额外开销

func ChainWithNext

func ChainWithNext[Ctx any](middlewares ...func(Ctx, func(Ctx) error) error) func(Ctx, func(Ctx) error) error

ChainWithNext 将中间件风格(接受"next"处理器)的函数组合在一起。

适用于构建中间件链,每个中间件可决定是否调用链中的下一个处理器。

并发安全性:返回的函数每次调用都会创建独立的执行状态,因此可并发调用。 但每条单独的调用链必须顺序执行(即单个中间件不得从多个 goroutine 并发调用 next())。

示例:

middleware := ChainWithNext[*context.Context](
    func(ctx *context.Context, next func(*context.Context) error) error {
        // 前置处理
        if err := validateAuth(ctx); err != nil {
            return err
        }
        // 调用下一个处理器
        if err := next(ctx); err != nil {
            return err
        }
        // 后置处理
        logRequest(ctx)
        return nil
    },
    // ... 更多中间件
)

func Conditional

func Conditional(condition context.Handler, thenHandler, elseHandler context.Handler) context.Handler

Conditional 根据条件选择执行不同的 Handler

先执行 condition Handler,如果成功则执行 thenHandler,否则执行 elseHandler。

使用场景:

  • 根据上下文条件执行不同的逻辑
  • 实现条件分支

示例:

isAdmin := func(ctx *context.Context) error {
    if !ctx.HasPermission("admin") {
        return errors.New("not admin")
    }
    return nil
}

adminHandler := func(ctx *context.Context) error {
    return ctx.Reply("Admin panel")
}

userHandler := func(ctx *context.Context) error {
    return ctx.Reply("User panel")
}

handler := helper.Conditional(isAdmin, adminHandler, userHandler)
eng.OnCommand("/panel").Handle(handler)

注意:

  • elseHandler 可以为 nil,此时条件失败会直接返回 condition 的错误

func ExtractChatID deprecated

func ExtractChatID(e platform.Event) string

ExtractChatID 从平台无关事件中提取会话 ID。

Deprecated: 直接使用 e.Chat().ID,本函数只是其 nil 安全包装。

func ExtractContent deprecated

func ExtractContent(e platform.Event) string

ExtractContent 从平台无关事件中提取消息文本内容。

Deprecated: 直接使用 platform.Content(e),本函数只是其 nil 安全包装。

func ExtractSenderID deprecated

func ExtractSenderID(e platform.Event) string

ExtractSenderID 从平台无关事件中提取发送者 ID。

Deprecated: 直接使用 e.Sender().ID,本函数只是其 nil 安全包装。

func FNVHash deprecated

func FNVHash(s string) string

FNVHash 计算字符串的FNV-1a哈希值并返回十六进制字符串。

Deprecated: 使用 infra/bytesconv.FNVHash。

func HideURL

func HideURL(url string) string

HideURL 隐藏URL

Example
url := "https://example.com/secret"
hidden := HideURL(url)
fmt.Println(hidden)
Output:
🔒example点com/secret

func Parallel

func Parallel(handlers ...context.Handler) context.Handler

Parallel 并行执行多个 Handler

所有 Handler 在独立的 goroutine 中并行执行。 等待所有 Handler 完成后,如果有任何错误,返回所有错误的组合。

使用场景:

  • 需要同时执行多个独立的操作
  • 提高 I/O 密集型操作的性能
  • 并行获取多个数据源

示例:

fetchUserData := func(ctx *context.Context) error {
    // 获取用户数据
    return nil
}

fetchProductData := func(ctx *context.Context) error {
    // 获取产品数据
    return nil
}

fetchOrderData := func(ctx *context.Context) error {
    // 获取订单数据
    return nil
}

handler := helper.Parallel(
    fetchUserData,
    fetchProductData,
    fetchOrderData,
)

eng.OnCommand("/dashboard").Handle(handler)

注意事项:

  • Handler 必须是并发安全的
  • 对 Context 的修改可能导致竞态条件
  • 所有 Handler 都会执行,即使某些失败
  • 如果多个 Handler 返回错误,所有错误会被组合返回

错误处理:

  • 使用 errors.Join() 组合所有错误
  • 只有在所有 Handler 完成后才返回

func Recover

func Recover(h context.Handler) context.Handler

Recover 包装 Handler,捕获 panic 并转换为 error

使用场景:

  • 保护关键的 Handler 不因 panic 而崩溃
  • 提供优雅的错误处理

示例:

riskyHandler := func(ctx *context.Context) error {
    // 可能 panic 的代码
    return nil
}

safeHandler := helper.Recover(riskyHandler)
eng.OnCommand("/risky").Handle(safeHandler)

func StringPipe

func StringPipe(funcs ...func(string) string) func(string) string

StringPipe 创建字符串转换管道。

这是为字符串预配置 Pipe 的便捷函数。

示例:

slugify := StringPipe(
    strings.TrimSpace,
    strings.ToLower,
    func(s string) string { return strings.ReplaceAll(s, " ", "-") },
)
slug := slugify("  Hello World  ")  // "hello-world"

func StringReplace

func StringReplace(old, new string) func(string) string

StringReplace 创建一个将所有 old 替换为 new 的函数。

func StringToBytes deprecated

func StringToBytes(s string) []byte

StringToBytes 以零拷贝方式把 string 转为只读 []byte。

Deprecated: 使用 infra/bytesconv.StringToBytes。

Example
str := "Hello, World!"
bytes := StringToBytes(str)
fmt.Printf("%d bytes\n", len(bytes))
Output:
13 bytes

func ToMiddleware

func ToMiddleware(h context.Handler) context.Middleware

ToMiddleware 将 Handler 转换为 Middleware

转换后的中间件会先执行该 Handler,如果成功则继续执行下一个 Handler。 如果 Handler 返回错误,不会调用 next Handler。

使用场景:

  • 将 Handler 逻辑作为中间件使用
  • 在 Handler 之前执行验证或预处理
  • 复用现有的 Handler 逻辑

示例:

validateAuth := func(ctx *context.Context) error {
    if !isAuthenticated(ctx) {
        return errors.New("unauthorized")
    }
    return nil
}

eng.OnCommand("/api").
    Use(helper.ToMiddleware(validateAuth)).
    Use(helper.ToMiddleware(parseInput)).
    Handle(businessLogic)

注意:

  • 如果 Handler 返回错误,中间件链会停止,不会调用后续中间件或 Handler
  • 与直接使用中间件的区别在于,这允许复用现有的 Handler 函数

Types

type Fn added in v1.41.0

type Fn[T any] func(T) T

Fn 是承载函数组合的具名函数类型(Go 1.27 泛型方法)。

通过 FnOf 构造后,可用 Pipe/Compose 方法组合数据转换管道。

func FnOf added in v1.41.0

func FnOf[T any](f func(T) T) Fn[T]

FnOf 将普通函数包装为 Fn。

func (Fn[T]) Compose added in v1.41.0

func (f Fn[T]) Compose(others ...func(T) T) Fn[T]

Compose 与 Pipe 类似,但以逆序应用函数。

遵循数学函数合成:f.Compose(g, h)(x) = f(g(h(x)))

示例:

composed := helper.FnOf(f).Compose(g, h)
result := composed(x) // 等同于 f(g(h(x)))

func (Fn[T]) Pipe added in v1.41.0

func (f Fn[T]) Pipe(others ...func(T) T) Fn[T]

Pipe 将当前函数与其它函数组合成管道,前一个函数的输出作为后一个函数的输入。

适用于构建数据转换管道。

示例:

transform := helper.FnOf(func(s string) string { return strings.TrimSpace(s) }).Pipe(
    strings.ToLower,
    func(s string) string { return strings.ReplaceAll(s, " ", "-") },
)
slug := transform("  Hello World  ") // "hello-world"

type Seq added in v1.41.0

type Seq[T any] []T

Seq 是承载链式切片操作的具名切片类型(Go 1.27 泛型方法)。

示例:

numbers := []int{1, 2, 3, 4, 5}
evens := helper.From(numbers).Filter(func(n int) bool { return n%2 == 0 })
doubled := helper.From(numbers).Map(func(n int) int { return n * 2 })
sum := helper.From(numbers).Reduce(0, func(acc, n int) int { return acc + n })
found, ok := helper.From(numbers).Find(func(n int) bool { return n > 3 })

链式组合(Map 方法自带类型参数 R):

helper.From(numbers).
    Filter(func(n int) bool { return n > 0 }).
    Map(func(n int) string { return fmt.Sprint(n) })

func From added in v1.41.0

func From[T any](slice []T) Seq[T]

From 将普通切片转换为 Seq,用于链式调用。

func (Seq[T]) Contains added in v1.41.0

func (s Seq[T]) Contains(target T) bool

Contains 报告 Seq 中是否存在与 target 相等的元素。

由于方法无法为接收者类型参数追加 comparable 约束,相等性通过 reflect.DeepEqual 判断(对 int/string 等常见类型与 == 一致)。

func (Seq[T]) Each added in v1.41.0

func (s Seq[T]) Each(fn func(T))

Each 对每个元素执行 fn(副作用遍历)。

func (Seq[T]) Filter added in v1.41.0

func (s Seq[T]) Filter(predicate func(T) bool) Seq[T]

Filter 返回满足谓词的元素组成的新 Seq。

func (Seq[T]) Find added in v1.41.0

func (s Seq[T]) Find(predicate func(T) bool) (T, bool)

Find 返回满足谓词的第一个元素,若未找到则返回零值。

func (Seq[T]) Map added in v1.41.0

func (s Seq[T]) Map[R any](fn func(T) R) Seq[R]

Map 对每个元素应用 fn,返回新元素类型的 Seq(方法自带类型参数 R)。

func (Seq[T]) Reduce added in v1.41.0

func (s Seq[T]) Reduce[R any](initial R, fn func(R, T) R) R

Reduce 使用累加器函数将 Seq 归约为单个值。

func (Seq[T]) Sort added in v1.41.0

func (s Seq[T]) Sort(less func(T, T) bool) Seq[T]

Sort 按 less 排序(稳定排序,原地修改),返回自身以便链式调用。

func (Seq[T]) Unwrap added in v1.41.0

func (s Seq[T]) Unwrap() []T

Unwrap 返回底层切片。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL