お!頑張っているなという顔している柴犬です。
ここ数日、というか2週間ほど RUST のトレイト周辺の理解に苦しんでいましたが、ちょっと光が見えてきました。
トレイトのソースを読むのが一番いいようです。
そのお陰、今回の投稿ができました。
概要
構造体の大小比較したい場合、条件次第で次のコードで可能です。
#[derive(PartialEq, PartialOrd)] struct Sline { f0: u32, f1: String, f2: String, } // 構造体のメソッド impl Sline { fn new(f0: u32, f1: &str, f2: &str) -> Self { Self { f0: 0, f1: f1.to_string(), f2: f2.to_string(), } } } fn main() { let s1 = Sline::new(1, "0234","15"); let s2 = Sline::new(5, "1234","13"); println!("{}", s1 > s2); }
上のコードを Rust Playground で実行すると次のようになります。
しかし、大小の判定は構造体の要素順でしかならないなど制約があるため、これを任意にしてできるようにしてみました。
考えたコード
構造体の要素 f0 を無視して大小を比較するようにしてみました。
use std::cmp::Ordering; // 構造体の定義 #[derive(Eq)] struct Sline { f0: u32, f1: String, f2: String, } // 構造体のメソッド impl Sline { fn new(f0: u32, f1: &str, f2: &str) -> Self { Self { f0: 0, f1: f1.to_string(), f2: f2.to_string(), } } } impl Ord for Sline { fn cmp(&self, other: &Self) -> Ordering { match (self.f1.cmp(&other.f1), self.f2.cmp(&other.f2)) { (Ordering::Greater, _) => Ordering::Greater, (Ordering::Equal, Ordering::Greater) => Ordering::Greater, (Ordering::Equal, Ordering::Equal) => Ordering::Equal, _ => Ordering::Less, } } } impl PartialOrd for Sline { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } } impl PartialEq for Sline { fn eq(&self, other: &Self) -> bool { self.f1 == other.f1 && self.f2 == other.f2 } } fn main() { let s1 = Sline::new(1, "1234","12"); let s2 = Sline::new(5, "1234","11"); println!("{}", s1 > s2); }
上のコードを Rust Playground で実行すると次のようになります。
要素 f0 を無視して大小を比較した結果になっています。
Ordering について
Ordering は、2 つの値を比較した結果を表す列挙型です。
pub enum Ordering {
Less,
Equal,
Greater,
}
例
let result = 1.cmp(&2);
result には Ordering::Less が格納されます。
let result = 1.cmp(&1);
result には Ordering::Equal が格納されます。
let result = 2.cmp(&1);
result には Ordering::Greater が格納されます。
変形
次の部分をいじれば要素の選択、比較順、昇順、降順を任意に変えれそうです。
impl Ord for Sline { fn cmp(&self, other: &Self) -> Ordering { match (self.f1.cmp(&other.f1), self.f2.cmp(&other.f2)) { (Ordering::Greater, _) => Ordering::Greater, (Ordering::Equal, Ordering::Greater) => Ordering::Greater, (Ordering::Equal, Ordering::Equal) => Ordering::Equal, _ => Ordering::Less, } } } // 略 impl PartialEq for Sline { fn eq(&self, other: &Self) -> bool { self.f1 == other.f1 && self.f2 == other.f2 } }