Go 1.28 草案三处改动:url.MustParse、net 类型 TextUnmarshaler、代理变量小写优先
Go 1.28 预计 2027 年 2 月发布,尚未正式发布。草案发布说明在 tip.golang.org/doc/next。下面三处改动分别落在 net/url、net 和 net/http。
net/url:MustParse 处理常量 URL
url.MustParse 返回解析后的 URL,解析出错则 panic。典型用法是用合法的 URL 字符串常量初始化包级变量:
var (
apiBase = url.MustParse("https://api.example.com/v1/")
webhook = url.MustParse("https://hooks.example.com/notify")
)
在这之前要写成这样:
var apiBase = mustURL("https://api.example.com/v1/")
func mustURL(raw string) *url.URL {
u, err := url.Parse(raw)
if err != nil {
panic(err)
}
return u
}
url.Parse 返回 (*url.URL, error),而包级变量初始化不能带 if 分支,原来只能自己包一层辅助函数。MustParse 省掉了这段样板。
取舍上,panic 只适合字面量——写下来就能确认合法。URL 来自配置文件、环境变量或用户输入时,仍然应该用 url.Parse 拿到 error,再决定是返回错误还是降级处理。
net:IPMask、IPNet、HardwareAddr 实现 TextUnmarshaler
net.IPMask、net.IPNet、net.HardwareAddr 三个类型现在都实现了 encoding.TextUnmarshaler。结构体字段直接用这些类型,json.Unmarshal 就能从字符串填进去:
type Listener struct {
CIDR net.IPNet
Mask net.IPMask
MAC net.HardwareAddr
}
var l Listener
if err := json.Unmarshal(data, &l); err != nil {
return err
}
解码端既能识别这些类型当前的序列化格式,也能识别一个计划中的未来格式。当前格式是 Base64 编码,未来格式是可读的 JSON 格式,并会在后续 Go 版本中成为默认。这是一个两步走的过程:本版本 Go 生成的 JSON 仍能被更早版本的 Go 读取。
对使用者来说,眼下 JSON 里的 IPNet、HardwareAddr 依然是不直观的 Base64 串。想让配置文件里的人直接看懂,还是得自己转成 CIDR 或 MAC 字符串。这次真正变化的只有解码路径:用新版本 Go 编译的程序可以先接受未来格式,不必等默认值真正切换。
net/http:代理环境变量小写优先
ProxyFromEnvironment 现在优先使用小写的代理环境变量——http_proxy、https_proxy、no_proxy。当大小写两组变量都被设置且值不同时,小写生效:
export HTTP_PROXY=http://proxy-a.example:3128
export http_proxy=http://proxy-b.example:3128
上面这种情况走 proxy-b。只设置其中一组时,行为不变。改动也会扩展到 DefaultTransport 和 DefaultClient 的默认代理查找,也就是直接用 http.Get 之类的默认客户端时同样适用。
取舍方面,小写优先与多数命令行工具的读取习惯一致,容器和 CI 里通常也用小写变量配置代理,两套变量并存时不容易再出现「本地明明设了却没走对出口」的问题。需要注意的是,显式构造 Transport 并自己设置 Proxy 函数时,查找逻辑由那支函数决定,不受这条规则影响。