![](/img/trans.png)
[英]error: type parameter `D` must be used as the type parameter for some local type
[英]Why do the coherence rules raise the error “the type parameter must be used as the type parameter for some local type”?
為什么代碼示例1編譯但示例2給出了編譯錯誤?
例1:
use std::ops::Index;
struct Bounded {
idx: usize,
}
impl Index<Bounded> for [i32; 4] {
type Output = i32;
fn index(&self, b: Bounded) -> &i32 {
unsafe { self.get_unchecked(b.idx) }
}
}
例2:
use std::ops::Index;
struct Bounded {
idx: usize,
}
impl<T> Index<Bounded> for [T; 4] {
type Output = T;
fn index(&self, b: Bounded) -> &T {
unsafe { self.get_unchecked(b.idx) }
}
}
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`)
--> src/main.rs:7:1
|
7 | impl<T> Index<Bounded> for [T; 4] {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
它確實歸結為“有一個很好的理由”,但好的理由並不是那么復雜。
這是問題所在。 想象一下,我有一個圖書館箱子:
// library.rs
pub struct Dog;
pub trait Speak {
fn speak(&self);
}
還有兩個使用該庫箱的板條箱。
// bark.rs
extern crate library;
impl library::Speak for library::Dog {
fn speak(&self) {
println!("woof");
}
}
// woof.rs
extern crate library;
impl library::Speak for library::Dog {
fn speak(&self) {
println!("bark");
}
}
現在,出於某種原因,我想使用這兩個庫:
// main.rs
extern crate library;
extern crate woof;
extern crate bark;
fn main() {
let rex = library::Dog;
rex.speak();
}
該程序應該輸出什么? 有兩個同樣有效,難以區分的library::Speak
實現library::Speak
for library::Dog
; 沒有正確的答案。 更糟糕的是,如果我最初依賴於woof
,並且稍后添加了bark
,我的代碼將停止編譯,或者 - 更糟糕的是 - 開始透明地做錯事。 沖突的特質沖動是一件壞事™。
添加泛型時會變得更糟。 如果你有:
// barkgeneric.rs
extern crate library;
impl<T> library::Speak for T {
fn speak(&self) {
println!("woof");
}
}
// woofgeneric.rs
extern crate library;
impl<T> library::Speak for T {
fn speak(&self) {
println!("bark");
}
}
你現在有無數的沖突特質沖動。 哎呦。
為了避免這個問題,我們有了孤兒規則。 孤兒規則的想法是確保任何impl Trait for Type
都有一個,只有一個,它可以被放置。 這樣,我們就不用擔心沖突了; 如果正確設置孤兒規則,它們應該是不可能的。
規則可以歸結為:當你impl
的類型特征,無論是性狀或類型必須來自當前的箱子。 這使得我所有相互矛盾的例子都行不通。 woof.rs
無法實現library::speak
for library::Dog
,因為它們都不是來自它的箱子。
同樣,你也不能impl<T> Index<Bounded> for [T; 4];
impl<T> Index<Bounded> for [T; 4];
因為[T; 4]
[T; 4]
並非來自你的箱子,而且rustc
已經確定Index<Bounded>
也不算來自你的箱子。
但是,它確實讓你的impl Index<Bounded> for [i32; 4]
impl Index<Bounded> for [i32; 4]
通過,因為在這種情況下, Index<Bounded>
確實來自你。 這可能是一個錯誤,但它也可能只是預期的行為; 孤兒規則比我在這里所說的稍微復雜一些,並且它們可能以奇怪的方式進行交互。
有關更多細節,請參閱rustc --explain E0117
, rustc --explain E0210
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.