Позволяет ли Rust определять порядок или частичный порядок для вашего типа и внешних типов?

#rust #comparison

Вопрос:

Допустим, я хочу определить свой собственный тип..

 struct MyString(String);
 

Позволяет ли Rust мне определить поведение при сравнении строки с другим типом, таким как an Option<MyString> ? Я хочу написать что-то вроде этого,

 impl std::cmp::PartialOrd<Option<MyString>> {
    fn partial_cmp(self, other: Option<MyString> ) {
    }
}
 

Но я получаю,

ошибка[E0116]: не удается определить присущий impl тип за пределами ящика, где тип определен [ … ], для типа, определенного за пределами ящика. […] определите и внедрите вместо этого признак или новый тип

Это сбивает меня с толку, потому что MyString это мой типаж. Является ли это нарушением согласованности?

Ответ №1:

Ваш синтаксис неверен. Вам также нужно внедриться ParialEq , потому PartialCmp что этого требует:

 #![allow(unused)]

use std::cmp::Ordering;

#[derive(Debug, PartialEq, Eq)]
struct MyString(String);

impl std::cmp::PartialOrd<Option<MyString>> for MyString {
    fn partial_cmp(amp;self, other: amp;Option<MyString>) -> Option<Ordering> {
        match other {
            None => None,
            Some(s) => s.0.partial_cmp(amp;self.0),
        }
    }
}

impl std::cmp::PartialEq<Option<MyString>> for MyString {
    fn eq(amp;self, other: amp;Option<MyString>) -> bool {
        match other {
            Some(s) => s.eq(self),
            None => false,
        }
    }
}

fn main() {
    let a = MyString("foo".to_string());
    println!("{:?}", a > None)
}

 

Ответ №2:

Ошибка

impl для типа за пределами ящика, где этот тип определен

Это потому, что я остановился for MyString на impl ... for MyString {} этом . Простая синтаксическая ошибка, которую можно исправить, добавив, что,

 impl std::cmp::PartialOrd<Option<MyString>> for MyString {
    fn partial_cmp(self, other: Option<MyString> ) {
`
 

Тогда я получаю гораздо более разумную ошибку

 error[E0277]: can't compare `MyString` with `Option<MyString>`
   --> src/main.rs:6:6
    |
6   | impl std::cmp::PartialOrd<Option<MyString>> for MyString {
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `MyString == Option<MyString>`
    |
    = help: the trait `PartialEq<Option<MyString>>` is not implemented for `MyString`