为什么 Rust 禁止现有类型的实现?
Why does Rust forbid implementations of existing types?
这是怎么...
impl String {
fn foo(&self) {
//...
}
}
...与此有何不同?
fn foo(s: &String) {
//...
}
然后,如果您在 crate 中定义特征,则可以扩展类型实现。为什么?
下面 source 指出了几种不同的论点,说明为什么人们无法实现包装箱之外的现有类型。
本地实现可能会被未来的实现破坏。例如,考虑 "you've locally defined Add on Vec<T>
as a concat operator, ... , and then ... after years of debate ... some mathy operation [is] to be performed instead. If you delete your impl and upgrade, your code will be ... broken2."
代码的可读性也将受到此更改的影响,即它可能使 "value of that reading far more transient3."
还有一个安全问题。考虑以下在技术上可行的场景,如果允许的话,即 "an attacker [could] find a change in an impl in [some] library, a call site in an application they wish to backdoor, and send a "重构“拉取请求 "accidentally" 将新的 impl 替换为旧的 impl 以创建漏洞,但他们的拉取可以从库中引用旧代码。他们可以将恶意实现嵌入到另一个 create4."
中的宏中
假设如果允许本地实现,则本地实现将是首选实现。这将“违反一致性 属性 [目前正在维护]5." This point can be further clarified through what is called the 'HashTable' problem5。
mod foo {
impl Hash for i32 { ... }
fn f(mut table: HashMap<i32, &'static str>) {
table.insert(0, "hello");
::bar::f(&table);
}
}
mod bar {
impl Hash for i32 { ... }
fn f(table: &HashMap<i32, &'static str>) {
assert_eq!(table.get(0), Some("hello"));
}
}
这是怎么...
impl String {
fn foo(&self) {
//...
}
}
...与此有何不同?
fn foo(s: &String) {
//...
}
然后,如果您在 crate 中定义特征,则可以扩展类型实现。为什么?
下面 source 指出了几种不同的论点,说明为什么人们无法实现包装箱之外的现有类型。
本地实现可能会被未来的实现破坏。例如,考虑 "you've locally defined Add on
Vec<T>
as a concat operator, ... , and then ... after years of debate ... some mathy operation [is] to be performed instead. If you delete your impl and upgrade, your code will be ... broken2."代码的可读性也将受到此更改的影响,即它可能使 "value of that reading far more transient3."
还有一个安全问题。考虑以下在技术上可行的场景,如果允许的话,即 "an attacker [could] find a change in an impl in [some] library, a call site in an application they wish to backdoor, and send a "重构“拉取请求 "accidentally" 将新的 impl 替换为旧的 impl 以创建漏洞,但他们的拉取可以从库中引用旧代码。他们可以将恶意实现嵌入到另一个 create4."
中的宏中
假设如果允许本地实现,则本地实现将是首选实现。这将“违反一致性 属性 [目前正在维护]5." This point can be further clarified through what is called the 'HashTable' problem5。
mod foo { impl Hash for i32 { ... } fn f(mut table: HashMap<i32, &'static str>) { table.insert(0, "hello"); ::bar::f(&table); } } mod bar { impl Hash for i32 { ... } fn f(table: &HashMap<i32, &'static str>) { assert_eq!(table.get(0), Some("hello")); } }