trait 和型別的方法同名的例子

linghuyichong發表於2019-12-25

下面的例子中,Trait中擁有foo方法,Foo型別中也有foo方法,並且為Foo實現特徵Trait時,在其中呼叫自己的foo方法,程式碼如下:

trait Trait {
    fn foo(&mut self, x: i32);
}

struct Foo;

impl Foo {
    fn foo(&self) {
        println!("Foo::foo");
    }
}

impl Trait for Foo {
    fn foo(&mut self, x: i32) {
        //self.foo();    //1、出錯點1 
        (&*self).foo();  //按照此方式或者Self::foo(self)呼叫ok
        println!("Trait::foo {}", x);
    }
}

fn main() {
    let mut a: Foo = Foo{};
    a.foo();
    //a.foo(3);  //2、出錯點2,此方式呼叫出錯
    Trait::foo(&mut a, 3);
    println!("Hello, world!");
}

描述

在上述程式碼中,出錯點1的位置,如果直接呼叫self.foo()會出錯,但是呼叫(&*self).foo()或者Self::foo(self)則編譯透過。

原因解釋

Rust在進行方法解析的時候試用的規則比較簡單,編譯器檢視方法“ receiver”(點之前的東西,在本例中為self,其型別為&mut Foo),並檢查它是否具有稱為foo的方法。如果沒有foo方法,則嘗試借用或取消引用接收方後,再次檢查是否有此方法。編譯器會一直重複此過程,直到找到匹配的方法為止。
在此例中,編譯器就會匹配到fn foo(&mut self, x: i32)方法,所以按照出錯點1的寫法會出錯,正確的方式是將顯示的呼叫,呼叫方式為:

(&\*self).foo()

或者

Self::foo(self)

描述

在main函式中使用以下程式碼呼叫:

let mut a: Foo = Foo{};
a.foo();

總是預設的呼叫Foo型別的foo方法,那麼如果要呼叫trait中的方法怎麼辦呢?如果直接使用以下程式碼會出錯(對應上述程式碼中的出錯點2):

a.foo(3); //出錯

那麼要呼叫trait中的方法怎麼辦呢?

解決方式

那麼Rust針對這種情況,有專門的呼叫方式,如下:

Trait::foo(&mut a, 3);

即試用trait名顯示呼叫即可。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
令狐一衝

相關文章