Golang中‘non-Separator characters’含义解惑(embed路径匹配问题)
Go embed通配符
*的匹配规则解析 你遇到的核心问题是://go:embed的通配符规则和filepath.Match的规则并不完全等价,官方文档里的non-Separator characters描述针对的是filepath.Match,但embed有自己的特殊处理逻辑。
两个关键规则差异
路径段内的
*(如stubs/*):
这种写法里的*遵循filepath.Match的规则,确实只匹配**非路径分隔符(/)**的字符序列,仅匹配stubs目录下的直接子项(文件或一级子目录),不会递归匹配更深的子目录内容。比如你的T1变量,用stubs/*只能嵌入stubs/hello.txt和stubs/xyz目录本身,无法直接嵌入stubs/xyz/zyx.txt——尝试用T1.ReadFile("stubs/xyz/zyx.txt")会报错。前缀式的
*(如stubs*):
这种写法是embed特有的规则,*会匹配所有以stubs开头的完整路径,包括路径中的/,也就是递归匹配stubs目录下的所有层级内容。你的T2变量用stubs*,会嵌入stubs/hello.txt、stubs/xyz目录以及stubs/xyz/zyx.txt,所以能成功读取后者。
为什么和filepath.Match描述不一致?
filepath.Match是通用的路径匹配工具,而//go:embed的通配符规则是针对模块文件系统优化的:
- 当通配符出现在路径段末尾(如
dir/*),遵循filepath.Match的段内匹配规则; - 当通配符出现在完整路径的末尾(如
dir*),则是前缀匹配,会跨越路径分隔符递归匹配所有子路径。
验证你的测试案例
- 对
T1(stubs/*):执行T1.ReadFile("stubs/xyz/zyx.txt")会返回file does not exist错误,因为*只匹配到stubs下的直接子项,无法深入到xyz目录内部。 - 对
T2(stubs*):所有以stubs开头的路径都被嵌入,所以能正常读取stubs/xyz/zyx.txt。
内容的提问来源于stack exchange,提问作者JeaYang
相关产品推荐
相关产品推荐

