这一点在官方书TRPL里解释得很清楚了吧,在10.2节,原文如下:But we can’t implement external traits on external types. For example, we can’t implement theDisplaytrait onVecwithin ouraggregatorcrate, becauseDisplayandVecare defined in the standard library and aren’t local to ouraggregatorcrate. This restriction is part of a property of programs calledcoherence, and more specifically theorphan rule, so named because the parent type is not present. This rule ensures that other people’s code can’t break your code and vice versa. Without the rule, two crates could implement the same trait for the same type, and Rust wouldn’t know which implementation to use.
大致的意思是:不能对外部的类型实现外部的trait。举个例子,不能在我们的代码/库里为Vec实现Display trait,因为二者都是标准库,相对于你的代码而言是外部的。这个限制是为了“一致性”或可以称为“孤儿原则”。这个原则可以保证别人用你库的时候不会破坏你库里函数的功能(同理,你不能破坏标准库函数的功能)。。。
其实就是防止你同时修改一个外部库的type和它自带的trait,这不是很好理解么。举个例子,假如你在你的代码里为string实现了一个trait “from”,原版可以直接把&str转为string,假设你实现的时候把&str的两边空白去掉再转为string。那么编译器会不知道到底该遵循哪个trait函数来转化&str。更进一步,假设允许你覆盖原有的trait,标准库里有一部分其他功能使用了这个&str -> string,那么你随意修改可能造成使用其他库的其他函数时产生不可知的后果或者直接崩溃。
显然,孤儿原则只是禁止你覆盖原有类型的原有trait。为i32新加功能,新加一个trait “fff”显然就不会影响到原有trait的使用。你还可以实现一个新的type:foo,然后impl已有的 trait “from”也是合法的。这些都肯定不会破坏第三方库的功能。
如果你想问为什么不能为已有的type的已有的trait实现没有的函数。我想大概是因为没必要,无论如何,你都得写trait xxx { fn yyy } 和 impl xxx for zzz { fn yyy },你无非就是少想一个trait的名字罢了。或许还和一些编译期优化有关,这我就不知道了。