请在提交问题之前回答以下问题。谢谢!
你在使用的 Go 版本是什么( go version
)?
版本 1.9
这个问题是否在最新版本中重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
Windows/amd64
问题
为 Clean
函数定义的算法有缺陷,而且没有忠实地实现。
特别是,定义有缺陷,因为幂等条件
Clean(Clean(x)) == Clean(x)
可能失败,如果 Separator
不是 '/'
,就像在 Windows 系统上一样。
实际上,根据算法文档,在 Windows 系统上 '/'
将不会被处理为 Separator
,直到最终转换为 Separator
。因此,应用 Clean
一次或两次(在第一个清理步骤结束时将 '/'
翻译为 Separator
)可能会返回不同的结果,与幂等条件相矛盾。
此外,算法实现略有偏差于文档。实际上,每个满足
os.IsPathSeparator(c) == true
的字符都被处理为 Separator
,而不仅仅是 Separator
,如算法定义所述。在 Windows 系统上,这对两者都是如此:'\\'
和 '/'
。
请注意,如果 os.IsPathSeparator('/')
对所有可用实现都为真,则 '/'
始终被处理为 Separator
。因此,尽管算法定义和实现中有错误,幂等性仍然可以神奇地保留。
建议
我建议澄清算法文档并按照以下方式调整实现。
文档
- 将第一句话更改为
Clean 返回一个与 path 通过纯粹的词汇处理等效的最短路径名。首先,它将任何斜杠替换为分隔符。然后,它将以下规则迭代应用,直到无法进行进一步处理: - 将句子中的
slash
更改为Separator
返回的路径以斜杠结尾 ... - 删除句子
最后,任何出现的斜杠都被替换为分隔符。
实现
- 在第一行添加以下语句
path = FromSlash(path) - 将任何表达式(如
os.IsPathSeparator(x)
)更改为
x == Separator - 将最后一行更改为:
return out.string()
8条答案
按热度按时间b0zn9rqh1#
请提供一个简短的程序,以演示此问题。谢谢...
2017年11月24日,09:55,larhun ***@***.***>写道:在提交问题之前,请回答以下问题。谢谢!您正在使用的Go版本是什么(go version)?1.9这个问题是否会在最新版本中重现?是您正在使用的操作系统和处理器架构是什么(go env)?Windows/amd64问题Clean函数定义的算法有缺陷,而且没有忠实地实现。特别是,定义有缺陷,因为如果Separator不是'/',则Clean(Clean(x)) == Clean(x)可能会失败,例如在Windows系统上。实际上,根据算法文档,在Windows系统上,'/'不会在最终转换为Separator之前被处理为Separator。因此,应用Clean一次或两次(在第一次清理步骤结束时将'/'转换为Separator)可能会返回不同的结果,与幂等条件相矛盾。此外,算法实现略有偏差。实际上,满足os.IsPathSeparator(c) == true的所有字符都被视为Separator处理,而不仅仅是Separator,如算法定义所述。在Windows系统上,这对两者都是正确的:'\'和'/'。请注意,如果os.IsPathSeparator('/')对于所有可用的实现都为真,那么'/'始终被处理为Separator。因此,尽管算法定义和实现存在错误,幂等性仍然可以得到保留。建议我提议澄清算法文档并按以下方式修改实现。文档更改第一句话为Clean通过纯粹的词汇处理返回与路径等效的最短路径名。首先,它将任何斜杠替换为Separator。然后,它迭代地应用以下规则,直到无法再进行进一步处理:将句子中的斜杠替换为Separator The returned path ends in a slash ...删除该句子最后,任何出现的斜杠都被替换为Separator。实现在第一行添加path = FromSlash(path)更改任何表达式,如os.IsPathSeparator(x)为x == Separator更改最后一行为:return out.string()——您收到此邮件是因为您订阅了此线程。直接回复此电子邮件,查看GitHub上的版本,或者静音该线程。
rn0zuynd2#
这个问题可以通过一个程序来证明,只有当
os.IsPathSeparator('/')
返回 false 时才会发生,而在我的 Windows 系统上从未发生过这种情况。因此,为了证明算法定义是有缺陷的,提供了一个修改后的
path/filepath
包:github.com/larhun/filepath
是原始版本的副本,除了Clean
函数中任何出现os.IsPathSeparator
的地方都被替换为IsPathSeparator
,定义如下:这个条件只对
Separator
成立,符合为Clean
函数定义的算法。然后,以下程序打印
false
。对于幂等函数,预期值是
true
。7gcisfzg3#
我是否理解正确,您的意思是问题只在满足某个条件时发生,但这个条件不可能发生?
zf2sa74q4#
不,我并不是这么说的。问题在于文档和实现之间的错误和不一致。
文档中写道:
Clean通过纯粹的词汇处理返回与path等效的最短路径名。它会迭代地应用以下规则,直到无法再进行进一步处理:
返回的路径以斜杠结尾,仅当它表示根目录,例如Unix上的"/"或Windows上的
C:\
。最后,任何出现的斜杠都被Separator替换。
如果这个过程的结果是一个空字符串,Clean返回字符串"."。
我说的是之前的算法是错误的,因为它表示在最终替换任何斜杠出现之前,只处理
Separator
。如果这个算法精确地实现了,那么在Windows系统上,Clean
函数将不能是幂等的,如提供的程序所示。然而,实现偏离了文档,并像
Separator
一样处理对os.IsPathSeparator
为真的任何字符。在Windows系统上,这包括斜杠。然后,神奇地,Clean
函数结果变得幂等,尽管算法错误且实现错误。文档不应该误导人。正确的算法应该首先用
Separator
替换斜杠。正确的实现应该按照算法所述执行。06odsfpq5#
如果实施有缺陷,如所声称的那样,必须有一种方法来证明与该缺陷实施相关的问题。但早些时候你写道:
问题只能通过程序来演示,如果os.IsPathSeparator('/')返回false,这在我的Windows系统上从未发生过。
os.IsPathSeparator('/')
是否在其他系统中返回false?因为如果没有这样的系统,那么我们就有一些相互矛盾的信息。31moq8wy6#
为了澄清我之前的笔记,有两个错误会导致正确的行为。
因此,
os.IsPathSeparator
没有为斜杠返回 false 的新系统实现,它就可以正常工作。为了源代码的质量,应该进行更改。我建议同时进行这两个更改。
bvk5enib7#
对这个包的任何更改都可能影响数百万导入它的用户。正确的行为应该是引起最少惊讶的行为,并遵循兼容性指南。
更改算法所涉及的风险是新算法将不正确(并且这种不正确性也将是不一致的)。文件路径处理很微妙,需要许多特殊情况才能正确处理。这可能是代码现在看起来的样子的原因。
在一个'/'不是分隔符的系统中,正确性又从何谈起呢?
sulc1iza8#
我认为没有必要更改实现。如果你认为我们应该更改文档,请务必发送一个pull请求。谢谢。