亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何測試特征對象之間的相等性?

如何測試特征對象之間的相等性?

Git
婷婷同學_ 2019-11-20 10:27:23
編者注:此代碼示例來自1.0之前的Rust版本,在語法上不是有效的Rust 1.0代碼。此代碼的更新版本會產生不同的錯誤,但是答案仍然包含有價值的信息。在以下情況下,我們似乎無法測試是否相等。為什么是這樣?有解決方法嗎?(我正在使用Rust 0.11)。trait A: PartialEq {}#[deriving(PartialEq)]enum T {Ta, Tb}impl A for T {}fn main() {  assert!(Ta == Ta);  assert!(Ta != Tb);  assert!(some_fn(&Ta, &Ta));  assert!(!some_fn(&Ta, &Tb));}fn some_fn(an_a: &A, another_a: &A) -> bool {    an_a == another_a// ERROR ^~~~~~~~~~~~ binary operation `==` cannot be applied to type `&A`}fn another_fn(an_a: &A + PartialEq, another_a: &A + PartialEq) -> bool {               // ERROR: ^~~~~~~~~ only the builtin traits can be used as closure or object bounds    an_a == another_a}
查看完整描述

3 回答

?
DIEA

TA貢獻1820條經驗 獲得超2個贊

這是特征的定義PartialEq:


pub trait PartialEq<Rhs = Self> 

where

    Rhs: ?Sized, 

{

    fn eq(&self, other: &Rhs) -> bool;


    fn ne(&self, other: &Rhs) -> bool { ... }

}

注意Self參數類型。這意味著eq()和ne()方法接受與實現程序相同類型的參數。例如:


impl PartialEq for i32 {

    fn eq(&self, other: &i32) -> bool { ... }

}


impl PartialEq for String {

    fn eq(&self, other: &String) -> bool { ... }

}

請注意如何實現other更改類型以反映該類型PartialEq。


這就是問題。在特征對象中,實際類型將被刪除并且在運行時不可用。這意味著不可能從特征對象獲得對具體類型的引用。特別是,你不能去&A到&T在你的榜樣。


這意味著不可能Self在特征對象上調用接受或返回類型的方法。確實,這些方法總是需要一個具體的類型,但是如果您只有一個特征對象,那么就沒有具體的類型,而且這種方法也無法以任何明智的方式起作用。


查看完整回答
反對 回復 2019-11-20
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

在弗拉基米爾·馬特維耶夫(Vladimir Matveev)的幫助下,我找到了一種方法,用于Any將我的特征轉換為具體類型,并測試結果的相等性:


// `Any` allows us to do dynamic typecasting.

use std::any::Any;


trait A {

    // An &Any can be cast to a reference to a concrete type.

    fn as_any(&self) -> &dyn Any;


    // Perform the test.

    fn equals_a(&self, _: &dyn A) -> bool;

}


#[derive(Debug, PartialEq)]

enum T {

    Ta,

    Tb,

}


// Implement A for all 'static types implementing PartialEq.

impl<S: 'static + PartialEq> A for S {

    fn as_any(&self) -> &dyn Any {

        self

    }


    fn equals_a(&self, other: &dyn A) -> bool {

        // Do a type-safe casting. If the types are different,

        // return false, otherwise test the values for equality.

        other

            .as_any()

            .downcast_ref::<S>()

            .map_or(false, |a| self == a)

    }

}


fn main() {

    assert_eq!(T::Ta, T::Ta);

    assert_ne!(T::Ta, T::Tb);

    assert!(some_fn(&T::Ta, &T::Ta));

    assert!(!some_fn(&T::Ta, &T::Tb));

}


fn some_fn(an_a: &dyn A, another_a: &dyn A) -> bool {

    // It works!

    an_a.equals_a(another_a)

}


查看完整回答
反對 回復 2019-11-20
  • 3 回答
  • 0 關注
  • 564 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號