2017-04-09 18 views
4

這是怎麼回事...Rust爲什麼禁止現有類型的實現?

impl String { 
    fn foo(&self) { 
     //... 
    } 
} 

...有什麼不同這個?

fn foo(s: &String) { 
    //... 
} 

然後,如果您在箱子中定義特徵,則可以擴展類型實現。爲什麼?

+6

培訓相關RFC:https://github.com/rust-lang/rfcs/issues/493。更具體地說,你可能想跳到討論的這一部分:https://github.com/rust-lang/rfcs/issues/493#issuecomment-266307203 – asteriskTheServer

+6

@asteriskTheServer:這聽起來像是評論中的一個很好的答案。你爲什麼不嘗試按照正確的答案進行按摩,並將評論作爲來源? –

+2

這裏似乎有一個可見性問題;你如何期望'String :: foo'的可見性被控制?特性支持添加新的方法:'特性Foo {fn foo(&self);)impl Foo for String {...}'在這裏'String :: foo'的可見性可以通過導入特徵來控制,不同特性實現'foo' – user4815162342

回答

2

下面source指出了幾個不同的參數,說明爲什麼人們無法實現一個箱子以外的現有類型。

  • 本地impl可以被未來的實現中斷。例如,考慮「你已經在本地定義了添加Vec<T>作爲一個concat操作符,...,然後......經過多年的辯論......一些mathy操作將被執行,如果你刪除了你的impl並升級,您的代碼將被破壞2「。

  • 代碼的可讀性也將受到這一變化的影響,也就是說,它可以使「讀書更爲短暫3之價值。」

  • 還有一個安全問題。考慮下面的情況,如果允許的話,這在技術上是可行的,也就是說,「攻擊者[可以]在[某些]圖書館中找到impl的更改,他們希望借殼的應用程序中的調用站點,併發送」重構「pull request」意外「地將新的impl替換爲舊的impl以創建一個漏洞,但他們的pull可以引用庫中的舊代碼,並且他們可以將敵對impl嵌入另一個創建的宏中4「。

  • 假設本地impl將是首選實現的情況下,如果允許本地impls。這將「違反目前正在維持的一致性財產5」。這一點可以通過所謂的「HashTable」問題來進一步闡明:5

    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")); 
        } 
    } 
    
相關問題