简体   繁体   中英

the trait `PartialEq<Option<_>>` is not implemented

I have a struct where I've derived a couple of things.

#[derive(PartialEq, Debug)]
    struct Subscriber {
        id: u16,
        up_speed: u32,
        down_speed: u32
    }

However, when I try to use PartialEq, I get told it is not implemented.

for (id, subscriber) in &new_hashmap {

        let original_subscriber = original_hashmap.get(id).unwrap();

        if original_subscriber == None {
            changed_hashmap.insert(subscriber.id, subscriber);
        } else if subscriber != original_subscriber {
            changed_hashmap.insert(subscriber.id, subscriber);
        }
    }

Here's the compiler error.

error[E0277]: can't compare `&Subscriber` with `Option<_>`
  --> src/main.rs:34:32
   |
34 |         if original_subscriber == None {
   |                                ^^ no implementation for `&Subscriber == Option<_>`
   |
   = help: the trait `PartialEq<Option<_>>` is not implemented for `&Subscriber`
   = help: the trait `PartialEq` is implemented for `Subscriber`

If I rewrite it to not put original_subscriber into its own variable, then it works.

for (id, subscriber) in &new_hashmap {

        if original_hashmap.get(id) == None {
            changed_hashmap.insert(subscriber.id, subscriber);
        } else if subscriber != original_hashmap.get(id).unwrap() {
            changed_hashmap.insert(subscriber.id, subscriber);
        }
    }

The rest of the code is essentially doing the following.

  1. Create HashMap of 2 Subscriber instances.
  2. Create another HashMap of 3 Subscriber instances, 1 of which is new, 1 of which is the same, and 1 of which has the same key but an updated value.

That is original_hashmap HashMap and new_hashmap.

The goal is to get a third HashMap of items in new_hashmap that are new to original_hashmap or have changed values.

your code does not work for 2 reasons.

  1. If you derive PartialEq it will only work for Subscriber == Subscriber checks. You need to implement PartialEq<Type>
  2. You are using a reference when comparing. This means you need to implement PartialEq for &Subscriber and not subscriber

This should do the trick

 #[derive(PartialEq, Debug)]
    struct Subscriber {
        id: u16,
        up_speed: u32,
        down_speed: u32,
    }

    let subscriber = Subscriber {
        id: 1,
        up_speed: 100,
        down_speed: 100,
    };

    impl PartialEq<Option<Subscriber>> for &Subscriber {
        fn eq(&self, other: &Option<Subscriber>) -> bool {
            match other {
                Some(other) => return other == *self,
                None => return false,
            }
        }
    }

    if &subscriber == None {
        println!("None");
    } else {
        println!("Some");
    }

But I am not sure if this is really what you want. I will try to implement the same and edit my answer afterwards

I suppose that's what you want to implement

use std::collections::HashMap;

#[derive(Debug, PartialEq)]
struct Subscriber {
    id: u16,
    up_speed: u32,
    down_speed: u32,
}

impl Subscriber {
    fn new(id: u16, up_speed: u32, down_speed: u32) -> Subscriber {
        Subscriber {
            id,
            up_speed,
            down_speed,
        }
    }
}

fn main() {
    let mut old_map = HashMap::new();
    old_map.insert(1, Subscriber::new(1, 1, 1));
    old_map.insert(2, Subscriber::new(2, 2, 2));

    let mut new_map = HashMap::new();
    new_map.insert(0, Subscriber::new(0, 0, 0)); //new
    new_map.insert(1, Subscriber::new(1, 1, 1)); //Same
    new_map.insert(2, Subscriber::new(3, 3, 3)); //Same key but different value

    let mut changed_map = HashMap::new();
    //
    for (key, subscriber) in &new_map {
        if old_map.contains_key(&key) {
            if old_map[&key] != *subscriber {
                changed_map.insert(key, subscriber);
            }
        } else {
            changed_map.insert(key, subscriber);
        }
    }

    println!("{:?}", changed_map);
}

It will return
{2: Subscriber { id: 3, up_speed: 3, down_speed: 3 }, 0: Subscriber { id: 0, up_speed: 0, down_speed: 0 }}

I used the deref operator to avoid impl PartialEq<Subscriber> for &Subscriber but you could have done that as well

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM