Сравните структуры, если реализован partialeq

#rust

Вопрос:

Как я могу сравнить общие структуры, если параметр типа T реализует PartialEq ? Я попробовал следующее, но оно не компилируется. Я понимаю, что могу просто сделать Foobar<T> вывод Eq и так далее, но возможно ли Foobar «наследовать» или PartialEq T как-то взять от? Я предполагаю , что что-то подобное уже сделано Vec , например, вы можете сравнить Vec s тогда и только тогда T , когда это возможно PartialEq .

 struct Foobar<T> {
    foobar: T
}

fn x() -> bool {
    let a = Foobar{foobar: 1};
    let b = Foobar{foobar: 2};
    a == b
}
 

Ответ №1:

Вы можете реализовать эту черту, ограничив реализацию, когда T PartialEq она слишком:

 impl<T> PartialEq for Foobar<T> where T: PartialEq {
    fn eq(amp;self, other: amp;Self) -> bool {
        self.foobar == other.foobar
    }
}
 

Игровая площадка

Хотя самым простым решением было бы вывести непосредственно:

 #[derive(PartialEq)]
struct Foobar<T> {
    foobar: T
}
 

Это также ограничит ваши внутренние типы этой чертой, это означает, что вы не сможете создать экземпляр Foobar структуры с чем-то, что не является PartialEq :

 #[derive(PartialEq)]
struct Foobar<T> {
    foobar: T
}

struct NonPartialEq {}

fn main() {
    let a = Foobar{foobar: NonPartialEq {}};
    let b = Foobar{foobar: NonPartialEq {}};
    assert!(a != b)
}
 

Что-то подобное не будет компилироваться с:

 error[E0369]: binary operation `!=` cannot be applied to type `Foobar<NonPartialEq>`
  --> src/main.rs:11:15
   |
11 |     assert!(a != b)
   |             - ^^ - Foobar<NonPartialEq>
   |             |
   |             Foobar<NonPartialEq>
   |
   = note: an implementation of `std::cmp::PartialEq` might be missing for `Foobar<NonPartialEq>`
 

Таким образом, реализация его hanb с помощью ограничения позволит вам использовать вашу структуру для любого типа, но вы все равно сможете использовать PartialEq ее, когда внутренний тип будет таким.

Ответ №2:

Что касается Vec<_> того, что полезно прокрутить его документацию, чтобы увидеть, что существует реализация признака, которая распространяется Eq так, как вы хотите.

 impl<T, A> Eq for Vec<T, A> where
    T: Eq,
    A: Allocator, 
 

Так что вам нужно сделать то же самое:

 struct Foobar<T> {
    foobar: T
}

impl<T> PartialEq for Foobar<T> where T: PartialEq {
    fn eq(amp;self, other: amp;Self) -> bool {
        self.foobar == other.foobar
    }
}
impl<T> Eq for Foobar<T> where T: Eq {}

fn x() -> bool {
    let a = Foobar{foobar: 1};
    let b = Foobar{foobar: 2};
    a == b
}

fn main() {
    println!("{}", x()); // false
}

 

Комментарии:

1. Спасибо за ссылку на документацию! Я нахожу документацию немного трудной для анализа, я, вероятно, не знал бы, что искать для начала.

2. Я уверяю вас, что документация Rust — это лучшее, что может ответить на многие вопросы. Просто нужно к этому привыкнуть