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

convert

package
v0.29.0 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package convert 提供常用类型转换工具函数。

所有转换函数都支持默认值,转换失败时返回默认值而非 error。

convert.Str2Int64("123", 0)     // 123
convert.Str2Int64("abc", 0)     // 0 (转换失败返回默认值)
convert.Str2Float64("3.14", 0)  // 3.14
convert.Bool2Str(true)          // "true"

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AnyToBool

func AnyToBool(v any) bool

AnyToBool 任意类型转 bool,无法转换返回 false。 数值类型非零为 true;字符串按 strconv.ParseBool 解析。

func AnyToFloat32

func AnyToFloat32(v any) float32

AnyToFloat32 任意类型转 float32,无法转换返回 0。

func AnyToFloat64

func AnyToFloat64(v any) float64

AnyToFloat64 任意类型转 float64,无法转换返回 0。 支持 bool(true=1, false=0)、string/[]byte(按浮点解析)、所有数值类型。

func AnyToInt

func AnyToInt(v any) int

AnyToInt 任意类型转 int,无法转换返回 0。

func AnyToInt64

func AnyToInt64(v any) int64

AnyToInt64 任意类型转 int64,无法转换返回 0。 支持 bool(true=1, false=0)、string/[]byte(按十进制解析)、所有数值类型。

func AnyToStr

func AnyToStr(v any) string

AnyToStr 任意类型转字符串。

func AnyToUint64

func AnyToUint64(v any) uint64

AnyToUint64 任意类型转 uint64,无法转换返回 0。 注意:传入负数会按位重新解释为大正数(uint 语义),调用方应自行确保非负。

func AppendStrings

func AppendStrings(a, b []string) []string

AppendStrings 将 b 切片追加到 a 切片。

func Bool2Str

func Bool2Str(b bool) string

Bool2Str bool 转字符串。

func BoolToBytes

func BoolToBytes(b bool) []byte

BoolToBytes bool 转字节切片。

func ByteToBytes

func ByteToBytes(b byte) []byte

ByteToBytes 单个字节转字节切片。

func BytesToFloat32

func BytesToFloat32(data []byte) float32

BytesToFloat32 字节切片转 float32,失败返回 0。

func BytesToFloat64

func BytesToFloat64(data []byte) float64

BytesToFloat64 字节切片转 float64,失败返回 0。

func BytesToInt

func BytesToInt(data []byte) int

BytesToInt 字节切片转 int,失败返回 0。

func BytesToInt64

func BytesToInt64(data []byte) int64

BytesToInt64 字节切片转 int64,失败返回 0。

func BytesToString

func BytesToString(data []byte) string

BytesToString 字节切片转字符串。

func Convert

func Convert(data any, target any) error

Convert 通过 JSON 序列化/反序列化将 data 转换到 target。 注意:此方法会丢失精度,不适用于需要精确转换的场景。

func ConvertStruct

func ConvertStruct(src, dst any) error

ConvertStruct 将 src 结构体的同名字段映射到 dst。 dst 必须是指针。通过反射匹配字段名,相同名称且类型兼容的字段会被复制。

type Src struct { Name string; Age int }
type Dst struct { Name string; Age int }
var d Dst
ConvertStruct(Src{Name: "test", Age: 18}, &d)

func DeepCopy

func DeepCopy(value any) any

DeepCopy 对 JSON 动态数据(map[string]any / []any 递归嵌套)进行深拷贝。 仅处理 any 承载的动态容器;强类型容器(如 []map[string]any、 map[string][]string)与其他类型原样返回(浅拷贝),调用方自行注意。

func DefaultTrustedProxies added in v0.25.2

func DefaultTrustedProxies() []string

DefaultTrustedProxies 返回默认可信代理 CIDR 列表的副本。

返回副本而非包级切片本身:包级切片一旦被调用方改写(append / 排序 / 改元素), 会静默改变本包 GetClientIP 的判定口径。框架适配层(如 Hertz 侧)用本函数 取同一份默认口径,避免各框架各抄一份内网网段清单后各自漂移。

func Float32ToStr

func Float32ToStr(f float32, prec int) string

Float32ToStr float32 转字符串,prec 为小数位数(-1 为最短表示)。

func Float64ToBytes

func Float64ToBytes(f float64, prec int) []byte

Float64ToBytes float64 转字节切片,prec 为小数位数。

func Float64ToStr

func Float64ToStr(f float64, prec int) string

Float64ToStr float64 转字符串,prec 为小数位数(-1 为最短表示)。

func GetClientIP

func GetClientIP(r *http.Request) string

GetClientIP 从 HTTP 请求中提取真实客户端 IP。 优先级:X-Forwarded-For(仅当请求来自可信代理时) > RemoteAddr。

⚠️ 本函数**不采信 X-Real-IP**——单跳头无法区分「代理写的」与「客户端自带的」, 网关默认透传客户端自带的该头,采信它等于把客户端 IP 的决定权交给客户端 (pkg#106)。确实需要时用 GetClientIPWithXRI。

安全说明:默认只信任内网代理(10/8, 172.16/12, 192.168/16, 127/8)。 如果部署在公网代理后面(如 Cloudflare),需要通过 GetClientIPWithProxies 指定可信代理列表。

func GetClientIPWithProxies

func GetClientIPWithProxies(r *http.Request, trustedProxies []string) string

GetClientIPWithProxies 从 HTTP 请求中提取真实客户端 IP,指定可信代理清单。 只有当 RemoteAddr 属于可信代理时,才信任 X-Forwarded-For。 trustedProxies 为 nil 或空时,只使用 RemoteAddr。

⚠️ 本函数**不采信 X-Real-IP**(同 GetClientIP)。

本函数是 net/http 适配层,算法本体在 ResolveClientIP(非 net/http 框架也可复用)。

func GetClientIPWithProxiesAndXRI added in v0.26.0

func GetClientIPWithProxiesAndXRI(r *http.Request, trustedProxies []string) string

GetClientIPWithProxiesAndXRI 指定可信代理清单并额外采信 X-Real-IP。

前置条件同 GetClientIPWithXRI:可信代理必须覆写 X-Real-IP。

func GetClientIPWithXRI added in v0.26.0

func GetClientIPWithXRI(r *http.Request) string

GetClientIPWithXRI 在 GetClientIP 的基础上额外采信 X-Real-IP。

仅在可信代理会**覆写** X-Real-IP 时使用(否则客户端可任意改写自己的客户端 IP, pkg#106)。

func Int32ToStr

func Int32ToStr(i int32) string

Int32ToStr int32 转字符串。

func Int64ToBytes

func Int64ToBytes(i int64) []byte

Int64ToBytes int64 转字节切片(十进制文本)。

func Int64ToStr

func Int64ToStr(i int64) string

Int64ToStr int64 转字符串。

func IntToBytes

func IntToBytes(i int) []byte

IntToBytes int 转字节切片(十进制文本)。

func IntToStr

func IntToStr(i int) string

IntToStr int 转字符串。

func ResolveClientIP added in v0.25.2

func ResolveClientIP(remote, xff string, trustedProxies []string) string

ResolveClientIP 是框架无关的客户端 IP 解析纯函数——HTTP 框架只负责把 「对端地址 + X-Forwarded-For 头」取出来,采信判定全部在本函数内。

入参:

  • remote:对端地址,形态为 "ip:port" 或裸 IP(IPv4 / IPv6);解析不出端口时按原样当 IP 用。
  • xff:X-Forwarded-For 头原文,多段以逗号分隔。
  • trustedProxies:可信代理清单(CIDR 或裸 IP);nil 或空时只认 remote(代理头一律忽略)。

采信规则:

  • remote 不在可信代理内 ⇒ 返回 remote,**忽略一切代理头** (直连方可以随意伪造 XFF,任何代理头都不可信)。
  • remote 在可信代理内 ⇒ 从 XFF **右向左**扫描,跳过可信代理, 返回第一个非可信 IP;XFF 整条链都是可信代理(如内网互调)⇒ 回退到最左端的 原始发起方;XFF 缺失或整条链都没有合法 IP ⇒ 返回 remote。

为什么从右向左:XFF 语义是每个代理把上一跳追加到右端,左侧是客户端可任意伪造的; 从左向右扫描会把攻击者注入的伪造值当成客户端 IP(限流 key / 审计 / 访问控制被绕过)。

候选值合法性:XFF 的每一段都必须能归一为合法 IP 才参与判定——非法段直接跳过, 不进返回值。理由有二:任意字符串进限流/锁定键等于「伪造 IP 永不命中计数 = 绕过」, 且可注入任意内容污染审计日志;带端口的候选归一为裸 IP,避免同一客户端换个端口 就换一个分桶键(pkg#104)。

与 v0.25.2 的差异(BREAKING):

  • **不再读取 X-Real-IP**。X-Real-IP 是单跳头,HTTP 头本身无法区分 「代理写的」与「客户端自带的」——大量网关(Envoy / Higress / Traefik)默认 不写该头,但会**原样透传**客户端自带的 X-Real-IP,于是 XFF 那条有右向左 可信链保护的路径与 XRI 这条没有保护的路径信任强度不对等:客户端可以任意 改写自己的客户端 IP(pkg#106)。需要采信 X-Real-IP 的部署请显式调用 ResolveClientIPWithXRI。
  • 裸 IP 形态的可信代理条目现在生效(此前被静默忽略,pkg#104)。
  • 候选值带端口时归一为裸 IP;非法候选值不再进入返回值。

清单形态的调用每次请求都会重新解析清单(热路径不划算);高 QPS 场景请用 NewTrustedProxySet 构造一次、之后走 ResolveClientIPWithSet(pkg#107)。

清单里的非法条目在本形态下被跳过(历史口径,函数签名无法回报错误);需要 fail-fast 的配置加载路径请用 NewTrustedProxySet。

func ResolveClientIPWithSet added in v0.26.0

func ResolveClientIPWithSet(remote, xff string, set *TrustedProxySet) string

ResolveClientIPWithSet 用预解析的可信代理集合解析客户端 IP(热路径形态)。

与 ResolveClientIP 的采信规则逐字相同,差别只有一处:清单在构造期解析一次, 请求期不再逐条 ParseCIDR(pkg#107)。set 为 nil 时等价于「不信任任何代理头」。

func ResolveClientIPWithSetAndXRI added in v0.26.0

func ResolveClientIPWithSetAndXRI(remote, xff, xri string, set *TrustedProxySet) string

ResolveClientIPWithSetAndXRI 是 ResolveClientIPWithSet 与 X-Real-IP 采信的组合。

与 ResolveClientIPWithXRI 同样的前置条件:可信代理必须覆写 X-Real-IP, 否则客户端可任意改写自己的客户端 IP(pkg#106)。

func ResolveClientIPWithXRI added in v0.26.0

func ResolveClientIPWithXRI(remote, xff, xri string, trustedProxies []string) string

ResolveClientIPWithXRI 在 ResolveClientIP 的基础上**额外**采信 X-Real-IP。

仅在部署形态能保证「可信代理会覆写(而非追加/透传)X-Real-IP」时使用—— 例如 nginx 的 proxy_set_header X-Real-IP $remote_addr(覆写语义)。 若可信代理只是透传客户端自带的 X-Real-IP,本函数等同于把客户端 IP 的决定权 交给客户端:限流/锁定计数桶可被绕过,审计与访问日志的来源 IP 可被改写 (pkg#106)。

func Str2Bool

func Str2Bool(s string, def bool) bool

Str2Bool 字符串转 bool,失败返回默认值。 接受 "1", "t", "T", "TRUE", "true", "True" 为 true。

func Str2Float32

func Str2Float32(s string, def float32) float32

Str2Float32 字符串转 float32,失败返回默认值。

func Str2Float64

func Str2Float64(s string, def float64) float64

Str2Float64 字符串转 float64,失败返回默认值。

func Str2Int

func Str2Int(s string, def int) int

Str2Int 字符串转 int,失败返回默认值。

func Str2Int32

func Str2Int32(s string, def int32) int32

Str2Int32 字符串转 int32,失败返回默认值。

func Str2Int64

func Str2Int64(s string, def int64) int64

Str2Int64 字符串转 int64,失败返回默认值。

func Str2Uint

func Str2Uint(s string, def uint) uint

Str2Uint 字符串转 uint,失败返回默认值。 负数字符串会解析失败并返回默认值。

func Str2Uint64

func Str2Uint64(s string, def uint64) uint64

Str2Uint64 字符串转 uint64,失败返回默认值。 负数字符串会解析失败并返回默认值。

func StringToBytes

func StringToBytes(s string) []byte

StringToBytes 字符串转字节切片。

func StructToMap

func StructToMap(v any) map[string]any

StructToMap 将结构体转为 map[string]any。 通过 json tag 获取 key 名,无 json tag 则用字段名。

func Uint64ToStr

func Uint64ToStr(u uint64) string

Uint64ToStr uint64 转字符串。

func UintToStr

func UintToStr(u uint) string

UintToStr uint 转字符串。

Types

type TrustedProxySet added in v0.26.0

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

TrustedProxySet 是预解析的可信代理集合。

存在的理由:按清单逐条 net.ParseCIDR 的写法每请求都要把整份清单重新解析一遍 (清单 N 条 ⇒ 每请求 N 次 ParseCIDR),而解析结果在清单不变时是恒定的 (pkg#107)。构造期解析一次、请求期只做网段包含判定,热路径成本降为一次 预解析 + 若干次位运算。

本类型不可变:构造后只读,可安全跨 goroutine 共享。

func NewTrustedProxySet added in v0.26.0

func NewTrustedProxySet(proxies []string) (*TrustedProxySet, error)

NewTrustedProxySet 解析可信代理清单为预解析集合(严格模式:非法条目返回错误)。

条目形态:

  • CIDR("10.0.0.0/8"):按原样使用;
  • 裸 IP("203.0.113.5"):归一为单主机网段(IPv4 /32、IPv6 /128);
  • 其它:解析失败即返回错误,**不静默跳过**。

为什么裸 IP 必须归一而不是忽略:清单里写 "203.0.113.5" 的本意是「信任这一台 代理」,而 net.ParseCIDR 对裸 IP 解析失败,旧实现直接 continue —— 于是配置 **不生效且无任何告警**(pkg#104):可信代理悄悄退化成「不信任任何代理头」, 表现为限流 key 变成代理 IP、审计里看不到真实客户端,而查配置看不出任何异常。

为什么非法条目必须报错而不是静默跳过:静默跳过把「配置写错」变成「安全策略 降级」且不可观测;fail-fast 让配置在加载期就红。

空清单合法(等价于「不信任任何代理头」,fail-closed)。

func (*TrustedProxySet) Contains added in v0.26.0

func (s *TrustedProxySet) Contains(ip net.IP) bool

Contains 判断 IP 是否落在集合内;集合为空或 IP 非法时返回 false。

func (*TrustedProxySet) ContainsString added in v0.26.0

func (s *TrustedProxySet) ContainsString(ipStr string) bool

ContainsString 判断字符串形态的 IP 是否落在集合内;解析失败返回 false。

func (*TrustedProxySet) Len added in v0.26.0

func (s *TrustedProxySet) Len() int

Len 返回集合内的网段条数。

Jump to

Keyboard shortcuts

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