Rust中没有命名空间是一项功能

2020-09-12 00:07:14

Rust的包管理系统中没有名称空间。它通常被认为是一个漏洞。但这不是bug,而是一种功能!虽然平面程序包注册表有负面影响,但也有真正的好处。稳定性、连续性和统一性(不鼓励分叉和支离破碎的身份)。寻求添加名称空间而不解决其删除的积极方面的建议可能不会被接受。

我注意到,现行制度的好处似乎只是作为对建议的反对而顺便提及,而从未在任何地方概述过。这是一种通过总结我读过的各种提案中提出的观点来解决这一问题的尝试。虽然我不代表crates.io团队(我甚至不在团队中),但我希望准确地表示正在考虑的权衡。

身份在包裹管理中的作用有着深远的影响。我看到的大多数命名空间提案的动机都是试图解决当前包标识系统的驻留和/或调整问题。然而,crates.io登记处的结构影响的不仅仅是这些领域。但我们将从身份的基础开始,并从那里开始工作。

你怎么指代包裹?板条箱至少有三个我能想到的标识:*crates.io-每个名称正好有一个板条箱*Cargo.toml-每个名称正好有一个板条箱*代码中使用的默认名称-每个名称可以有多个,这在实践中很少见*代码中使用的实际名称-这可以通过Cargo.toml或externs语句进行控制,但不需要重命名。

前两个称为正在发布的板条箱的cargo.toml中的Package.name。第三个可以通过正在发布的包中的lib.name被覆盖。最后一个是用户控制的。通常,所有这些名称都是匹配的,但需要注意的是,破折号在代码中是下划线(在将破折号规范化为下划线之后,crates.io不允许有两个具有相同crates.io名称的箱子)。

可以说,从可发现性的角度来看,不言而喻的身份比其他身份更有优势。例如,如果你是单打独斗的话,乍一看,argparse可能比clap更有声望。

平面注册表使身份管理(命名机箱)变得更加困难。你要么选择一个GUID(哈哈,请不要选择),要么选择一些值得记住的(但可能大部分或完全无关的)身份。我认为这是寻求添加名称空间或以其他方式解决蹲点问题提案的主要驱动力。

目前,身份是连续的-板条箱的身份是不变的,这有真正的好处。如果你想要改变身份系统,你必须确保身份不会在你的领导下改变。这是对任何允许名称空间所有权意外更改的名称空间系统的打击。不连续的身份认同有几个问题。

首先,如果板条箱的名称可以更改,这对用户来说是不好的。如果他们想要更新,就必须找出软件包的新名称。

其次,如果身份的机箱可以更改(如果身份是可重用的,这是前面这一点的结果),那么您就引入了一个安全漏洞。在不同所有权下更新到具有不同内容的新包版本是一个真正的安全风险。如果您在非故意的所有权更改之后不禁止在最后一个主要版本上使用新的次要版本,就更是如此。人们应该审计他们的板条箱吗?是!。但是我们的步枪越少越好。

除了防止安全问题外,提案还需要鼓励交易过渡。循序渐进地移动,而不是全有或全无。这可以更多地被视为兼容性,而不是连续性。这推动了诸如铁锈版本和名称空间提议向后兼容的需求。

“铁锈”的核心宗旨是稳定。显而易见的定义是,昨天编译的东西应该在今天编译(即使使用新的编译器)。

一个不太明显的定义是,添加新的依赖项不应该阻止您编译已经在工作的代码。这是孤儿规则的主要动机(尽管孤儿规则比这更微妙)。这是对鼓励多个不同的箱子在代码中具有相同默认名称的方案的打击。我认为任何鼓励这一点的提案都不可能获得批准。它还建议我们应该禁止板条箱默认代号与其Package/Cargo.toml名称不同的新实例。

除了代码稳定性之外,crates.io也应该是稳定的。它应该能够将自己与外部服务隔离开来。它目前依赖于Github,但它并不一定要这样。这是对将名称空间标识与任何外部托管系统相结合的任何系统的打击。

目前的身份系统鼓励蹲点。我会把蹲守定义为在没有实际使用的情况下预留一个板条箱。这是生锈生态系统的自然结果,原因有两个:

板条箱易于发布,因此很容易通过发布空箱来预订板条箱

一个包名只能有一个版本。例如,只有一个http板条箱。因此,包名是一种稀缺资源。

在crates.io上有很多人蹲着。不过,我没有确切的数字。

我们对蹲着也没有任何结构化的支持,这使得我们很难区分好演员和坏演员。我认为将它们分离出来需要人工干预,而crates.io团队规模很小,没有太多时间去做这件事。

那么什么是糟糕的演员呢?我认为那些蹲在一堆板条箱里制作、指向或防止他们的名字被用来演戏的人是一个糟糕的演员。Crates.io有一项政策,禁止使用自动化来要求板条箱的所有权,但我并没有太多听说它会被强制执行。再说一次,时间是个问题。这可能也会扩展到名称空间所有权。

我确实认为有合法的用途。为您正在工作的项目预留一组扩展板条箱就是一个例子。我的另一个例子是保留一个您真正打算使用的板条箱(这个更值得商榷)。

考虑到这个系统,很难提出一个在某种程度上不损害当前系统的命名空间方案。

我想说最紧张的是代码级的身份。它们要么通过砍掉名称空间部分变得重叠,要么通过包含名称空间部分变得更长。前面的几点说明了为什么重叠通常被认为是不可能的。对于更长的标识,您需要想出一些新的方法来在不会破坏内容的代码中引用名称空间。

不过更重要的是,据我所见,大多数提出身份方案的人提出它是为了让生态系统能够支持重叠的板条箱身份(例如,多个http板条箱)。而这正是当前系统避免做的事情。

下面引用CAD97中的一句话(希望相当准确),总结了名称空间对相关各方的意义:

对于板条箱团队来说,这似乎主要意味着一个项目可以将多个包放在一个保护伞下,这样您就知道这些包是由项目确定的。

对于那些对这里的crates团队的方法感到最不屑一顾的人来说,命名空间主要是指能够发布具有所需名称的箱子,即使已经发布了提供具有该名称的箱子的包,方法是将包放到不同的命名空间中,这样名称就不会发生冲突。

如果后一方询问“名称空间”并表示后者,而团队回答并表示前者,您就可以看到误解是从哪里开始的,特别是因为crates团队现在已经在这里传达了这样的立场,即一般情况下,Package.name==lib.name错误不应该更多;也就是说,后一组的目标是来自crates团队的一个明显不需要的属性。

还有其他一些关于命名空间的建议,它们不是关于重叠的身份,而是更多地关于管理和将相关的板条箱分组在一起。那里有多个提案,每个提案都有自己的权衡。期待后续的帖子讨论其中的一些内容。

当我回顾过去的讨论时,我保存了一组很好的十几条评论:

关于crates.io政策的主要线索中都提到了命名空间和下蹲的主题: