utility

package module
v0.0.0-...-2439b48 Latest Latest
Warning

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

Go to latest
Published: Mar 2, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

README

🛠️ Utility

Go Version


📖 项目简介 (Introduction)

🎯 一句话概述

Utility 是一个为 荒野地图 开发者打造的高性能通用工具库,专注于后端系统的基础设施建设。

💡 项目背景与价值

在后端开发过程中,开发者经常需要重复实现诸如 ID 生成、加密解密、网络通信、配置加载等基础功能。这些"轮子"的重复造就不仅浪费时间,还容易引入潜在的 bug 和性能问题。

Utility 应运而生,它提供了一套经过生产环境验证的、开箱即用的核心组件集合,涵盖:

  • 🔢 基础工具层:数值计算、ID 生成、加密解密、数据结构
  • 🌐 网络通信层:多协议服务器(TCP/KCP/WebSocket)、连接管理
  • 🏗️ 应用框架层:模块化架构、生命周期管理、事件总线
  • 📦 中间件集成:RabbitMQ 客户端、日志系统、脚本执行器
  • ⚙️ 配置管理层:TSV 热加载、类型安全解析
🎯 主要应用场景
  • 游戏服务器开发:坐标计算、战斗逻辑、状态管理、配置热更新
  • 微服务架构:分布式 ID、消息队列、服务通信、日志追踪
  • 高并发系统:网络连接管理、协议多路复用、优雅关闭
  • 数据密集型应用:加密传输、配置管理、脚本动态执行

✨ 核心特性 (Features)

⚡ 高性能基础库
  • 🆔 IDGen (分布式 ID 生成器)

    • 基于改进的 Snowflake 算法(42 位时间戳 + 21 位序列号)
    • 支持 139 年时间跨度,每秒生成 210 万唯一 ID
    • 线程安全,支持高并发场景
    • 内置时间戳与序列号提取功能
  • 🔍 Accuracy (浮点数精度比较)

    • 解决浮点数 == 比较的精度误差问题
    • 提供 EqualGreaterSmaller 等高级比较方法
    • 支持自定义精度阈值(Epsilon / LowEpsilon)
    • 适用场景:游戏坐标、金融计算、物理模拟
  • 🔐 Crypto (企业级加密工具)

    • RSA-OAEP:非对称加密,支持 PKCS#1/PKCS#8 密钥格式
    • AES-GCM:认证加密(推荐),提供机密性与完整性双重保护
    • AES-CTR:流式加密,适合大数据加密
    • 统一的 ICrypter 接口设计,便于算法切换
  • 📊 高性能数据结构

    • Flag:64 位标记系统,内存占用仅 8 字节,支持位运算
    • TopN:泛型 Top-N 容器,自动维护最大/最小 N 个元素
    • SortMap:Map 排序工具,支持按键/值升降序排序
🛠️ 强大的模块组件
  • 🏗️ App Framework (应用框架)

    • 模块化架构设计,支持动态模块加载/卸载
    • 完整的生命周期管理(Init → Run → Close)
    • 内置 ChanRPC 通道,支持模块间异步通信
    • 支持模块状态监控与统计
  • 🌐 XNet (多协议网络服务器)

    • 协议支持:TCP、KCP(可靠 UDP)、WebSocket
    • 连接复用:基于 cmux 的智能协议分流
    • 高并发设计:Goroutine Pool、连接计数、优雅关闭
    • 安全特性:支持 HAProxy PROXY 协议、Panic 恢复
    • 跨平台:支持 Windows 命名管道、Unix Domain Socket
  • 📄 TSV Config (配置管理)

    • 支持热加载(文件变更自动重载)
    • 泛型设计,类型安全的配置访问
    • 支持 JSON 嵌套字段解析
    • 自动类型转换(int/float/bool/string/json)
    • 线程安全读写
  • 📢 Event Bus (事件总线)

    • 轻量级进程内发布/订阅模式
    • 支持监听器优先级排序
    • 快速注册接口(QuickRegister
    • 自动清理空监听集合,防止内存泄漏
  • 📝 XLog (高性能日志)

    • 基于 Uber Zap 构建,性能极致
    • 提供 Sugar 风格的便捷 API
    • 支持结构化日志与格式化日志
    • 灵活的日志级别控制
  • 🐍 XExec (脚本执行器)

    • 支持 Python、Shell、PowerShell、Batch 脚本
    • 环境变量隔离与工作目录控制
    • 实时输出捕获(stdout/stderr)
    • 超时控制与优雅终止
    • 注入式测试支持(便于单元测试)
  • ⏰ XTime (时间工具库)

    • 时间偏移功能(用于测试/调试时间相关逻辑)
    • 毫秒/秒/微秒级时间戳转换
    • 支持 UTC 与本地时间切换
    • 今日零点、下一日零点等常用时间计算
  • 🐰 XAMQP (RabbitMQ 客户端)

    • 封装 amqp091-go,简化 RabbitMQ 操作
    • 自动重连机制,支持连接断线重试
    • 声明式队列/交换机/绑定管理
    • 支持发布/订阅、工作队列等模式

🚀 使用指南 (Usage)

1. 安装依赖
# 获取最新版本
go get github.com/wildmap/utility@latest

# 或指定版本
go get github.com/wildmap/[email protected]
2. 快速开始
🆔 分布式 ID 生成 (IDGen)
package main

import (
	"fmt"
	"github.com/wildmap/utility"
)

func main() {
	// 生成全局唯一 ID
	id := utility.NextID()
	
	fmt.Printf("ID: %d\n", id.Int64())          // 数值形式
	fmt.Printf("String: %s\n", id.String())     // 字符串形式
	fmt.Printf("生成时间: %v\n", id.Time())       // 提取时间戳
	fmt.Printf("序列号: %d\n", id.Seq())          // 提取序列号
	
	// 从字符串解析 ID
	parsed, _ := utility.ParseString("123456789")
	fmt.Printf("解析结果: %d\n", parsed.Int64())
}

输出示例:

ID: 187649984473252865
String: 187649984473252865
生成时间: 2026-02-03 15:17:30 +0800 CST
序列号: 1
🔍 浮点数精度比较 (Accuracy)
package main

import (
	"fmt"
	"github.com/wildmap/utility"
)

func main() {
	// 普通比较(错误示范)
	a, b := 0.1+0.2, 0.3
	fmt.Printf("0.1 + 0.2 == 0.3: %v\n", a == b)  // false(精度问题)
	
	// 使用 Accuracy 比较(正确做法)
	fmt.Printf("Equal: %v\n", utility.Equal(a, b))              // true
	fmt.Printf("Greater: %v\n", utility.Greater(1.02, 1.0))     // true
	fmt.Printf("GreaterOrEqual: %v\n", utility.GreaterOrEqual(1.005, 1.0)) // true(近似相等)
}
🔐 加密解密 (Crypto)
package main

import (
	"fmt"
	"github.com/wildmap/utility"
)

func main() {
	// 1. AES-GCM 认证加密(推荐用于数据传输)
	key := []byte("1234567890123456") // 16 bytes (AES-128)
	crypter, _ := utility.NewAESGCMCrypter(key)
	
	plaintext := []byte("敏感数据")
	ciphertext, _ := crypter.Encrypt(plaintext)
	decrypted, _ := crypter.Decrypt(ciphertext)
	
	fmt.Printf("原文: %s\n", plaintext)
	fmt.Printf("密文: %x...\n", ciphertext[:16]) // 十六进制显示
	fmt.Printf("解密: %s\n", decrypted)
	
	// 2. RSA 非对称加密(用于密钥交换)
	publicKeyPEM := []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`)
	
	encrypter, _ := utility.NewRSAEncrypter(publicKeyPEM)
	encrypted, _ := encrypter.Encrypt([]byte("secret key"))
	fmt.Printf("RSA 加密: %x...\n", encrypted[:16])
}
🏴 位标记管理 (Flag)
package main

import (
	"fmt"
	"github.com/wildmap/utility"
)

// 定义权限标志
const (
	PermRead    utility.Flag = 1 << 0  // 0x01 读权限
	PermWrite   utility.Flag = 1 << 1  // 0x02 写权限
	PermExecute utility.Flag = 1 << 2  // 0x04 执行权限
	PermDelete  utility.Flag = 1 << 3  // 0x08 删除权限
)

func main() {
	var userPerms utility.Flag
	
	// 设置权限
	userPerms.Set(PermRead | PermWrite)
	fmt.Printf("权限值: %08b\n", userPerms)  // 二进制: 00000011
	
	// 检查权限
	fmt.Printf("有读权限: %v\n", userPerms.Include(PermRead))        // true
	fmt.Printf("有写和执行权限: %v\n", userPerms.Include(PermWrite | PermExecute)) // false
	fmt.Printf("有读或执行权限: %v\n", userPerms.IncludeAny(PermRead | PermExecute)) // true
	
	// 清除权限
	userPerms.Clean(PermWrite)
	fmt.Printf("清除写权限后: %08b\n", userPerms)  // 00000001
}
📊 Top-N 排序容器
package main

import (
	"fmt"
	"github.com/wildmap/utility"
)

type Player struct {
	Name  string
	Score int
}

func main() {
	// 维护分数最高的 3 名玩家
	topN := utility.NewTopN[Player](3, func(a, b Player) int {
		return a.Score - b.Score  // 按分数升序排列
	})
	
	// 添加玩家
	players := []Player{
		{"Alice", 95}, {"Bob", 87}, {"Charlie", 92},
		{"David", 78}, {"Eve", 99},
	}
	
	for _, p := range players {
		topN.Put(p)
	}
	
	// 遍历前 3 名
	fmt.Println("排行榜 Top 3:")
	topN.Range(func(i int, p Player) bool {
		fmt.Printf("%d. %s: %d 分\n", i+1, p.Name, p.Score)
		return false
	})
}

输出:

排行榜 Top 3:
1. Eve: 99 分
2. Alice: 95 分
3. Charlie: 92 分
📄 TSV 配置加载

配置文件:config/items.tsv

ID	Name	Level	Attributes
编号	名称	等级	属性
#int	string	int	json
1001	铁剑	5	{"atk": 50, "def": 10}
1002	钢盾	8	{"atk": 20, "def": 80}
1003	法杖	10	{"atk": 100, "magic": 200}

加载代码:

package main

import (
	"fmt"
	"github.com/wildmap/utility/tsv"
)

type ItemConf struct {
	ID         int                    `json:"ID"`
	Name       string                 `json:"Name"`
	Level      int                    `json:"Level"`
	Attributes map[string]interface{} `json:"Attributes"`
}

func main() {
	// 加载配置(Key 为 int 类型的 ID)
	conf, err := tsv.New[int, *ItemConf]("./config")
	if err != nil {
		panic(err)
	}
	
	// 获取单个配置
	if item := conf.Get(1001); item != nil {
		fmt.Printf("物品: %s (Lv.%d)\n", item.Name, item.Level)
		fmt.Printf("攻击力: %.0f\n", item.Attributes["atk"])
	}
	
	// 遍历所有配置
	conf.Range(func(id int, item *ItemConf) bool {
		fmt.Printf("[%d] %s\n", id, item.Name)
		return false  // 返回 true 可中断遍历
	})
}
📡 网络服务器 (XNet)
package main

import (
	"context"
	"fmt"
	"github.com/wildmap/utility/xlog"
	"github.com/wildmap/utility/xnet"
)

// 实现 IAgent 接口
type GameAgent struct {
	conn xnet.IConn
}

func (a *GameAgent) OnInit(ctx context.Context) error {
	xlog.Infof("客户端连接: %s", a.conn.RemoteAddr())
	return nil
}

func (a *GameAgent) Run(ctx context.Context) {
	for {
		// 读取消息
		msg, err := a.conn.ReadMsg()
		if err != nil {
			xlog.Errorf("读取消息失败: %v", err)
			return
		}
		
		xlog.Infof("收到消息: %s", string(msg))
		
		// 回复消息
		response := []byte(fmt.Sprintf("服务器收到: %s", msg))
		if err := a.conn.WriteMsg(response); err != nil {
			xlog.Errorf("发送消息失败: %v", err)
			return
		}
	}
}

func (a *GameAgent) OnClose(ctx context.Context) {
	xlog.Infof("客户端断开: %s", a.conn.RemoteAddr())
}

func main() {
	// 创建支持 TCP/WebSocket/KCP 的服务器
	server := xnet.NewServer(":8080", func(conn xnet.IConn) xnet.IAgent {
		return &GameAgent{conn: conn}
	})
	
	xlog.Info("启动游戏服务器...")
	if err := server.Start(); err != nil {
		panic(err)
	}
	
	// 优雅关闭(通常在信号处理中调用)
	// server.Stop()
}
📢 事件总线 (Event)
package main

import (
	"fmt"
	"github.com/wildmap/utility/event"
)

func main() {
	bus := event.NewFacade()
	
	// 注册监听器(支持优先级)
	bus.QuickRegister("user.login", 10, func(data map[string]any) {
		fmt.Printf("用户登录: %s\n", data["username"])
	})
	
	bus.QuickRegister("user.login", 5, func(data map[string]any) {
		fmt.Println("记录登录日志")  // 优先级低,后执行
	})
	
	// 触发事件
	bus.Fire("user.login", map[string]any{
		"username": "Alice",
		"ip":       "192.168.1.100",
	})
}

输出(按优先级排序):

用户登录: Alice
记录登录日志
🐍 脚本执行 (XExec)
package main

import (
	"fmt"
	"github.com/wildmap/utility/xexec"
)

func main() {
	// 执行 Python 脚本
	script := xexec.NewPythonScript("print('Hello from Python!')")
	output, err := script.Run()
	if err != nil {
		panic(err)
	}
	fmt.Printf("Python 输出: %s\n", output)
	
	// 执行 Shell 命令(跨平台)
	shellScript := xexec.NewShellScript("echo 'Hello World'")
	shellOutput, _ := shellScript.Run()
	fmt.Printf("Shell 输出: %s\n", shellOutput)
}
⏰ 时间工具 (XTime)
package main

import (
	"fmt"
	"github.com/wildmap/utility/xtime"
	"time"
)

func main() {
	// 获取当前时间戳
	fmt.Printf("当前毫秒时间戳: %d\n", xtime.NowTs())
	fmt.Printf("当前秒时间戳: %d\n", xtime.NowSecTs())
	
	// 时间戳转换
	ms := xtime.NowTs()
	t := xtime.Ms2Time(ms)
	fmt.Printf("时间对象: %v\n", t)
	
	// 时间偏移(用于测试)
	xtime.SetUseOffset(true)
	xtime.AddOffset(24 * time.Hour)  // 将当前时间推进一天
	fmt.Printf("偏移后时间: %v\n", xtime.Now())
	
	// 今日零点
	todayStart := xtime.TodayStartTs()
	fmt.Printf("今日零点: %s\n", xtime.FormatMs(todayStart))
}

Documentation

Index

Constants

View Source
const (
	// Epsilon 高精度浮点数误差阈值(10^-8)。
	// 适用于科学计算、高精度数值模拟等对精度要求极高的场景。
	Epsilon = 0.00000001

	// LowEpsilon 低精度浮点数误差阈值(10^-2)。
	// 适用于一般业务逻辑、游戏开发、UI 布局等对精度要求适中的场景。
	// 本包所有比较函数默认使用此阈值。
	LowEpsilon = 0.01
)

Variables

View Source
var (
	// ErrInvalidPEMBlock 表示 PEM 格式解析失败,通常由文件损坏或格式不正确导致。
	ErrInvalidPEMBlock = errors.New("invalid PEM block")

	// ErrInvalidPrivateKey 表示私钥类型不匹配,非 RSA 私钥或密钥格式错误时触发。
	ErrInvalidPrivateKey = errors.New("invalid private key type")

	// ErrInvalidPublicKey 表示公钥类型不匹配,非 RSA 公钥或密钥格式错误时触发。
	ErrInvalidPublicKey = errors.New("invalid public key type")

	// ErrInvalidAESKeyLength 表示 AES 密钥长度非法。
	// 合法长度:16 字节(AES-128)、24 字节(AES-192)、32 字节(AES-256)。
	ErrInvalidAESKeyLength = errors.New("AES key length must be 16, 24, or 32 bytes")

	// ErrInvalidCiphertext 表示密文格式错误或数据被截断/篡改。
	ErrInvalidCiphertext = errors.New("invalid ciphertext")
)

加密操作相关的预定义错误。

Functions

func Abs

func Abs[T Integer](x T) T

Abs 返回任意数值类型的绝对值。

通过泛型实现,避免为每种数值类型单独编写重载函数。 注意:对 math.MinInt 取绝对值会发生溢出,调用方应自行处理边界情况。

func Equal

func Equal(a, b float64) bool

Equal 判断两个浮点数是否在误差范围内近似相等。

当两数之差的绝对值小于 LowEpsilon 时视为相等, 有效规避 IEEE 754 精度损失导致的"0.1 + 0.2 != 0.3"等经典问题。

func Filter

func Filter[T any](slice []T, predicate func(T) bool) []T

Filter 基于谓词函数过滤切片,返回所有满足条件的元素组成的新切片。

惰性分配:结果切片通过 append 动态扩容,避免预分配过多内存。 原切片保持不变,适合函数式风格的数据处理管道。

func FindIdx

func FindIdx[T cmp.Ordered](aim []T, value T) int

FindIdx 在切片中线性搜索目标值,返回首次出现的索引。

适用于无序切片的小规模查找(O(n))。 对于有序切片,建议使用 sort.SearchInts 等二分查找函数以获得 O(log n) 性能。 未找到目标值时返回 -1,与 strings.Index 等标准库保持一致的惯例。

func Greater

func Greater(a, b float64) bool

Greater 判断 a 是否明显大于 b,差值须超过 LowEpsilon 阈值。

区别于直接使用 > 运算符:当两数差值处于误差范围内时返回 false, 防止将近似相等的值误判为大于关系。

func GreaterOrEqual

func GreaterOrEqual(a, b float64) bool

GreaterOrEqual 判断 a 是否大于或近似等于 b。

满足以下任一条件即返回 true:

  • a 明显大于 b(差值超过 LowEpsilon)
  • a 与 b 近似相等(差值在 LowEpsilon 内)

func RandInterval

func RandInterval(b1, b2 int32) int32

RandInterval 在闭区间 [b1, b2] 内生成一个均匀分布的随机 int32 整数。

自动处理 b1 > b2 的情况(交换边界),因此参数顺序不影响结果。 当 b1 == b2 时直接返回该值,避免无意义的随机数计算。

func RandIntervalN

func RandIntervalN(b1, b2 int32, n uint32) []int32

RandIntervalN 在闭区间 [b1, b2] 内不重复地随机抽取 n 个整数。

基于 Knuth 洗牌算法(Fisher-Yates)的空间优化变体(Sattolo 算法思想): 使用 map 记录已"虚拟交换"的位置,无需实际构建完整数组, 时间复杂度 O(n),空间复杂度 O(n)(n 远小于区间长度时效率极高)。

当 n 超过区间长度时,自动截断为区间内所有整数。

func SliceDiff

func SliceDiff[V cmp.Ordered](a, b []V) []V

SliceDiff 计算切片 a 相对于切片 b 的差集,即仅在 a 中存在、b 中不存在的元素集合。

时间复杂度:O(n*m),其中 n 和 m 分别为 a 和 b 的长度。 对于大规模数据,建议先将 b 转换为 map 以将复杂度降至 O(n+m)。

func Smaller

func Smaller(a, b float64) bool

Smaller 判断 a 是否明显小于 b,差值须超过 LowEpsilon 阈值。

区别于直接使用 < 运算符:当两数差值处于误差范围内时返回 false, 防止将近似相等的值误判为小于关系。

func SmallerOrEqual

func SmallerOrEqual(a, b float64) bool

SmallerOrEqual 判断 a 是否小于或近似等于 b。

满足以下任一条件即返回 true:

  • a 明显小于 b(差值超过 LowEpsilon)
  • a 与 b 近似相等(差值在 LowEpsilon 内)

func ToCamelCase

func ToCamelCase(s string) string

ToCamelCase 将 snake_case 或其他分隔符风格的字符串转换为 CamelCase(大驼峰)。

支持的分隔符:下划线(_)、空格( )、连字符(-)、点号(.)。 算法逐字节扫描,通过 capNext 标志位控制下一个字母是否需要大写:

  • 连续大写字母序列(如 "XML")会被规范化("Xml"),防止与 Go 的命名风格冲突
  • 数字后的字母会自动大写(视为新单词的开始)

Types

type AESCTRCrypter

type AESCTRCrypter struct {
	// contains filtered or unexported fields
}

AESCTRCrypter 实现 AES-CTR(Counter Mode)流式加密。

CTR 模式通过对自增计数器加密生成密钥流,再与明文异或得到密文, 将块密码转换为流密码,支持任意长度数据的并行加解密。

重要:CTR 模式本身不提供数据完整性保护,若需防篡改, 应在加密后追加 HMAC-SHA256 认证,或直接使用 AES-GCM 模式。

func NewAESCTRCrypter

func NewAESCTRCrypter(key []byte) (*AESCTRCrypter, error)

NewAESCTRCrypter 创建 AES-CTR 加密器实例。

func (*AESCTRCrypter) Decrypt

func (c *AESCTRCrypter) Decrypt(ciphertext []byte) ([]byte, error)

Decrypt 使用 AES-CTR 模式解密密文。

CTR 模式的加解密操作完全对称(均为 XOR 操作), 解密过程与加密过程完全相同,只需正确提取 IV 并重建相同的密钥流即可。

func (*AESCTRCrypter) Encrypt

func (c *AESCTRCrypter) Encrypt(plaintext []byte) ([]byte, error)

Encrypt 使用 AES-CTR 模式加密明文,密文格式为 [IV | 密文]。

每次加密生成随机 IV(初始化向量,16字节,与 AES 块大小相同)并前置于密文。 CTR 模式的每次加密都应使用唯一的 IV,否则相同密钥下相同 IV 的密文可被异或破解。

type AESGCMCrypter

type AESGCMCrypter struct {
	// contains filtered or unexported fields
}

AESGCMCrypter 实现 AES-GCM(Galois/Counter Mode)认证加密。

GCM 模式是 CTR 模式与 GHASH 认证的组合,在提供加密机密性的同时, 通过 128 位认证标签(Authentication Tag)保证数据完整性, 任何对密文的篡改都会导致解密失败——这是区别于 AES-CTR 的核心优势。 推荐在绝大多数场景下优先使用此模式。

func NewAESGCMCrypter

func NewAESGCMCrypter(key []byte) (*AESGCMCrypter, error)

NewAESGCMCrypter 创建 AES-GCM 加密器实例。

密钥长度决定 AES 安全级别:

  • 16 字节 → AES-128(足以应对当前已知威胁)
  • 24 字节 → AES-192
  • 32 字节 → AES-256(政府机密级别)

func (*AESGCMCrypter) Decrypt

func (c *AESGCMCrypter) Decrypt(ciphertext []byte) ([]byte, error)

Decrypt 使用 AES-GCM 解密密文并验证认证标签。

若认证标签验证失败(数据被篡改或密钥不匹配),解密将返回错误而非静默失败, 这是 GCM 模式相比纯 CTR 模式的核心安全优势。

func (*AESGCMCrypter) Encrypt

func (c *AESGCMCrypter) Encrypt(plaintext []byte) ([]byte, error)

Encrypt 使用 AES-GCM 加密明文,密文格式为 [nonce | 密文 | 认证标签]。

每次加密通过 io.ReadFull 从 rand.Reader 生成唯一随机 nonce(12字节), 将 nonce 前置于密文便于解密时提取,无需额外传递 nonce。 注意:同一密钥下绝对不能重复使用 nonce,否则将完全破坏安全性。

type Flag

type Flag uint64

Flag 基于 uint64 的高性能位标记管理器。

利用位运算在单个 uint64 值中同时管理最多 64 个布尔标志, 所有操作均为 O(1) 时间复杂度,内存占用仅 8 字节。 相比 64 个独立 bool 字段节省 56 字节,且缓存友好性更佳。

使用场景:

  • 游戏角色状态管理(眩晕、无敌、沉默、隐身等)
  • 权限系统的权限位组合管理
  • 配置选项的功能开关组合
  • 网络协议头部的标志位字段

标志位定义惯例:

const (
    FlagRead   Flag = 1 << 0  // 0x01
    FlagWrite  Flag = 1 << 1  // 0x02
    FlagExec   Flag = 1 << 2  // 0x04
)

注意事项:

  • 标志位值应使用 1 << n 的形式定义(n: 0~63)
  • 避免使用 0 作为标志位,0 在位运算中无任何效果
  • 多个标志位可通过 | 运算符组合使用

func (*Flag) Clean

func (flag *Flag) Clean(f Flag)

Clean 清除一个或多个标志位(将对应位置 0)。

内部委托给 Exclude 实现,使用位清除运算(&^), 仅清除目标标志位,不影响其他位的状态。

func (*Flag) Equal

func (flag *Flag) Equal(s Flag) bool

Equal 判断两个 Flag 值是否完全相同(逐位比较)。

进行精确的全量匹配,所有 64 位都必须相同才返回 true。 与 Include 的包含关系检查不同,此方法不允许额外位的存在。

func (*Flag) Exclude

func (flag *Flag) Exclude(s Flag) Flag

Exclude 返回清除指定标志位后的新 Flag 值,不修改原值。

使用位清除运算(&^,Go 特有的 AND NOT 运算符)生成新值, 原 Flag 值保持不变,适合在链式操作或临时计算中使用。 如需就地修改,请使用 Flag.Clean 方法。

func (*Flag) Include

func (flag *Flag) Include(exp Flag) bool

Include 判断是否同时包含所有指定标志位(AND 语义)。

通过位与运算 (flag & exp) == exp 实现全量匹配, exp 中的每一个标志位都必须在 flag 中置位才返回 true。

典型用途:验证用户是否同时拥有一组权限。

func (*Flag) IncludeAny

func (flag *Flag) IncludeAny(exp Flag) bool

IncludeAny 判断是否包含至少一个指定标志位(OR 语义)。

通过位与运算 (flag & exp) != 0 实现任意匹配, exp 中只要有一个标志位在 flag 中置位即返回 true。

典型用途:验证用户是否拥有候选权限集合中的任意一个。

func (*Flag) Set

func (flag *Flag) Set(f Flag)

Set 设置一个或多个标志位(将对应位置 1)。

使用位或赋值(|=)实现,仅影响目标标志位,不改变其他位的状态。 重复设置已置位的标志是幂等操作,不会产生副作用。

type ICrypter

type ICrypter interface {
	// Encrypt 加密明文数据,返回密文字节数组。
	// AES 系列算法的密文中已内嵌 nonce/IV,解密时无需额外传递。
	Encrypt(data []byte) ([]byte, error)

	// Decrypt 解密密文数据,返回明文字节数组。
	// AES-GCM 解密会同时验证认证标签,若标签校验失败则返回错误,表明数据可能已被篡改。
	Decrypt(data []byte) ([]byte, error)
}

ICrypter 定义统一的加密解密接口。

所有加密实现(RSA、AES-GCM、AES-CTR)均实现此接口, 通过面向接口编程可在运行时灵活切换加密算法,降低业务代码与具体算法的耦合。

type ID

type ID int64

ID 表示一个全局唯一标识符,底层类型为 int64。

提供类型转换方法和从 ID 中提取时间戳、序列号的分析方法, 便于在排查问题时反解 ID 的生成时间和序列信息。

func NextID

func NextID() ID

NextID 使用全局生成器生成一个新的唯一 ID,是通常情况下的推荐调用方式。

func ParseID

func ParseID(id uint64) ID

ParseID 将 uint64 值转换为 ID 类型,用于从存储层或网络层反序列化 ID。

func ParseString

func ParseString(id string) (ID, error)

ParseString 将十进制字符串解析为 ID 类型,用于从 HTTP 请求参数等场景解析 ID。

func (ID) Bytes

func (i ID) Bytes() []byte

Bytes 返回 ID 十进制字符串的字节切片,适合写入 []byte 类型的字段。

func (ID) Float64

func (i ID) Float64() float64

Float64 将 ID 转换为 64 位浮点数,注意大整数转 float64 可能有精度损失。

func (ID) Int64

func (i ID) Int64() int64

Int64 将 ID 转换为有符号 64 位整数,适合存入数据库的 bigint 字段。

func (ID) Seq

func (i ID) Seq() uint64

Seq 从 ID 中提取并返回其序列号部分(低 21 位)。

序列号在同一秒内单调递增,可用于判断 ID 的生成顺序。

func (ID) String

func (i ID) String() string

String 返回 ID 的十进制字符串表示,便于 JSON 序列化和日志输出。

func (ID) Time

func (i ID) Time() time.Time

Time 从 ID 中提取并返回其生成时的时间戳(time.Time 对象)。

通过右移 timeShift 位取出高 42 位时间戳,再通过掩码确保仅取 42 位有效值, 最后转换为 time.Time,可用于调试、日志分析和按时间范围过滤 ID。

func (ID) Uint64

func (i ID) Uint64() uint64

Uint64 将 ID 转换为无符号 64 位整数,适合位运算或无符号数值处理场景。

type IDGenerator

type IDGenerator struct {
	// contains filtered or unexported fields
}

IDGenerator 线程安全的 ID 生成器,维护序列计数器和最后时间戳。

并发安全说明:通过 sync.Mutex 保护内部状态,所有并发调用均需获取锁, 确保同一时间戳内的序列号单调递增且不重复。

func NewGenerator

func NewGenerator() *IDGenerator

NewGenerator 创建并初始化 ID 生成器,记录当前时间戳作为起点。

func (*IDGenerator) NextID

func (s *IDGenerator) NextID() ID

NextID 生成下一个全局唯一 ID,线程安全。

序列号溢出处理策略: 当同一秒内序列号耗尽(超过 2^21)时,主动等待时间推进至下一秒, 而非回绕到 0,确保不同秒之间的 ID 不会出现重叠。

时间戳溢出(约 139 年后)将触发 panic,这是有意为之的防御性设计, 届时系统早应升级或迁移。

type Integer

type Integer interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
}

Integer 泛型数值类型约束,涵盖所有有符号整数和浮点数类型。

使用 ~ 前缀表示底层类型约束,允许基于这些类型定义的自定义类型也满足此约束, 增强了泛型函数对用户自定义数值类型的兼容性。

type Item

type Item[K, V any] struct {
	Key   K
	Value V
}

Item 表示 map 中的键值对元素,用于排序后的有序遍历。

使用结构体封装键值对而非使用匿名接口,保留了类型信息, 使调用方可以直接访问强类型的 Key 和 Value 字段,无需类型断言。

type Items

type Items[K, V any] []Item[K, V]

Items 已排序的键值对切片,提供对排序结果的进一步处理能力。

func ByFunc

func ByFunc[K comparable, V any](m map[K]V, c Less[K, V]) Items[K, V]

ByFunc 使用自定义比较函数对 map 进行排序,返回有序的键值对切片。

内部使用标准库 sort.Sort(内省排序算法),时间复杂度 O(n log n)。 返回的切片按 less 函数定义的顺序排列,调用方可直接遍历使用。

func ByKey

func ByKey[K Ordered, V any](m map[K]V) Items[K, V]

ByKey 按键的自然升序排序 map(键必须满足 Ordered 约束)。

利用标准库 cmp.Less 实现与 Go 内置排序一致的比较语义, 对字符串键会按字典序升序排列,对数值键会按数值升序排列。

func ByKeyDesc

func ByKeyDesc[K Ordered, V any](m map[K]V) Items[K, V]

ByKeyDesc 按键的自然降序排序 map(键必须满足 Ordered 约束)。

通过交换 cmp.Less 的参数顺序实现降序,无需额外实现。

func ByValue

func ByValue[K comparable, V Ordered](m map[K]V) Items[K, V]

ByValue 按值的自然升序排序 map(值必须满足 Ordered 约束)。

典型用途:按计数值从小到大排序统计结果。

func ByValueDesc

func ByValueDesc[K comparable, V Ordered](m map[K]V) Items[K, V]

ByValueDesc 按值的自然降序排序 map(值必须满足 Ordered 约束)。

典型用途:按得分从高到低排序排行榜数据。

func (Items[K, V]) Top

func (r Items[K, V]) Top(n int) Items[K, V]

Top 返回前 n 个元素的切片视图(共享底层数组,不复制)。

当 n 超过实际元素数量时,自动截断为全部元素,避免越界 panic。 适合在大量数据排序后仅关心 Top-N 结果的场景。

type Less

type Less[K, V any] func(x, y Item[K, V]) bool

Less 定义 map 元素的比较函数类型。

遵循 sort.Interface 的语义:当 x 应排在 y 之前时返回 true。 通过函数参数而非硬编码比较逻辑,使调用方可以自由定义升序、降序或自定义排序规则。

type Ordered

type Ordered cmp.Ordered

Ordered 所有可排序类型的约束别名,包含 cmp.Ordered 约束所覆盖的所有内置有序类型。

定义为类型别名而非直接使用 cmp.Ordered,便于在本包内统一表达排序语义, 同时保持与标准库的互操作性。

type RSADecrypter

type RSADecrypter struct {
	// contains filtered or unexported fields
}

RSADecrypter 使用 RSA 私钥和 OAEP 填充方案解密数据。

OAEP(Optimal Asymmetric Encryption Padding)相比传统 PKCS#1 v1.5 填充 能有效抵御选择密文攻击,是当前 RSA 加密的推荐填充方案。 内部采用 SHA-256 作为哈希函数,提供更强的安全性。

密钥格式支持:

  • PKCS#8(推荐):跨语言兼容性好,适合现代系统
  • PKCS#1(兼容旧系统):创建时自动回退尝试

func NewRSADecrypter

func NewRSADecrypter(priKey []byte) (*RSADecrypter, error)

NewRSADecrypter 解析 PEM 格式的 RSA 私钥并创建解密器实例。

解析策略:优先尝试 PKCS#8 格式,失败后自动回退至 PKCS#1 格式, 兼容新旧两种密钥格式,无需调用方手动区分。

func (*RSADecrypter) Decrypt

func (d *RSADecrypter) Decrypt(encryptedData []byte) ([]byte, error)

Decrypt 使用 RSA-OAEP(SHA-256)解密数据。

RSA 解密属于 CPU 密集型操作,2048 位密钥单次解密约耗时 1~2ms, 不适合高频或大数据场景,通常仅用于解密对称密钥本身(混合加密方案)。

type RSAEncrypter

type RSAEncrypter struct {
	// contains filtered or unexported fields
}

RSAEncrypter 使用 RSA 公钥和 OAEP 填充方案加密数据。

公钥加密,私钥解密——任何持有公钥的一方均可加密, 但只有持有对应私钥的一方才能解密,适合安全传递对称密钥等场景。

func NewRSAEncrypter

func NewRSAEncrypter(pubKey []byte) (*RSAEncrypter, error)

NewRSAEncrypter 解析 PKIX 格式的 PEM 公钥并创建加密器实例。

func (*RSAEncrypter) Encrypt

func (e *RSAEncrypter) Encrypt(originData []byte) ([]byte, error)

Encrypt 使用 RSA-OAEP(SHA-256)加密数据。

每次加密使用 rand.Reader 引入随机性,相同明文每次产生不同密文(概率加密), 有效防止密文分析攻击。

type TopN

type TopN[T any] struct {
	// contains filtered or unexported fields
}

TopN 维护 Top-N 最大(或最小)元素的有序容器。

通过自定义比较器定义"最大"的语义,自动维护容量为 n 的有序切片。 每次 Put 操作均保持切片有序,超出容量时自动丢弃末位元素。

时间复杂度:Put 操作为 O(n)(线性插入),Size/Get/Range 为 O(1)。 空间复杂度:O(n),仅保留 n 个元素。

典型用途:实时维护游戏排行榜 Top-N、统计最热门 N 个词等场景。

func NewTopN

func NewTopN[T any](n int, comparer func(a, b T) int) *TopN[T]

NewTopN 创建指定容量的 TopN 容器。

comparer 函数定义了元素的排序语义:

  • 返回正数表示 a > b(a 优先于 b,排在更前面)
  • 返回负数表示 a < b(b 优先于 a)
  • 返回 0 表示 a == b(同等优先级)

预分配 n 容量的底层切片,避免频繁扩容。

func (*TopN[T]) Get

func (t *TopN[T]) Get(i int) (T, bool)

Get 返回指定索引处的元素,索引越界时返回零值和 false。

func (*TopN[T]) GetAll

func (t *TopN[T]) GetAll() []T

GetAll 返回当前所有元素的深拷贝切片。

返回独立副本而非切片视图,防止调用方的修改影响内部状态, 是防御性编程的体现。

func (*TopN[T]) Put

func (t *TopN[T]) Put(item T)

Put 将新元素插入到有序切片的正确位置。

若容器已满且新元素不优于最末尾元素,则直接丢弃; 否则在找到正确位置后插入,并截断超出容量的末尾元素。

func (*TopN[T]) Range

func (t *TopN[T]) Range(f func(i int, item T) (abort bool))

Range 按排名顺序遍历所有元素,当回调函数返回 true 时提前终止遍历。

提前退出机制(abort=true)允许调用方在找到目标元素后立即停止, 避免无谓的全量遍历,对大容量 TopN 有明显性能提升。

func (*TopN[T]) Size

func (t *TopN[T]) Size() int

Size 返回当前容器中实际存储的元素数量(≤ n)。

Directories

Path Synopsis
timermgr
Package timermgr 提供基于多级时间轮算法的高性能定时器调度系统。
Package timermgr 提供基于多级时间轮算法的高性能定时器调度系统。
sockets
sockets 包提供创建和配置 Unix Domain Socket 及 TCP Socket 的辅助函数。
sockets 包提供创建和配置 Unix Domain Socket 及 TCP Socket 的辅助函数。

Jump to

Keyboard shortcuts

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