【Rust】mutexのvectorから指定した複数の値を削除する

普通のvectorから1つだけ削除

    let target = 2;
    let mut vec = vec![1, 2, 3, 4, 5];
    if let Some(remove_index) = vec.iter().position(|x| *x == target){
        vec.remove(remove_index);
    }
    println!("{:?}", vec);

[1, 3, 4, 5]

vectorから複数削除する

    let targets = [2, 4];
    let mut vec = vec![1, 2, 3, 4, 5];
    for target in targets {
        if let Some(remove_index) = vec.iter().position(|x| *x == target){
            vec.remove(remove_index);
        }
    }
    println!("{:?}", vec);

[1, 3, 5]

vectorの中身が構造体の時
=> 基本同じ処理

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct Person {
    last: String,
    first: String,
    age: i32
}
//
    let mut vec: Vec<Person> = Vec::new();
    let person1 = Person{last:"yamada".to_string(), first:"taro".to_string(), age: 20};
    let person2 = Person{last:"yoshida".to_string(), first:"akira".to_string(), age: 15};
    let person3 = Person{last:"takahashi".to_string(), first:"kazumi".to_string(), age: 21};
    let person4 = Person{last:"ichiba".to_string(), first:"kumi".to_string(), age: 22};
    let person5 = Person{last:"okamoto".to_string(), first:"hajime".to_string(), age: 17};
    vec.push(person1.clone());
    vec.push(person2.clone());
    vec.push(person3.clone());
    vec.push(person4.clone());
    vec.push(person5.clone());
    

    let mut engineers:Vec<Person> = Vec::new();
    engineers.push(person1);
    engineers.push(person2);

    for engineer in engineers {
        if let Some(remove_index) = vec.iter().position(|x| *x == engineer){
            vec.remove(remove_index);
        }
    }
    println!("{:?}", vec);

[Person { last: “takahashi”, first: “kazumi”, age: 21 }, Person { last: “ichiba”, first: “kumi”, age: 22 }, Person { last: “okamoto”, first: “hajime”, age: 17 }]

### mutexのvectorの場合
=> うまくいかない

static VECT: Lazy<Mutex<Vec<Person>>> = Lazy::new(|| Mutex::new(vec![]));

#[tokio::main]
async fn main() {

    let mut vec: Vec<Person> = Vec::new();
    let person1 = Person{last:"yamada".to_string(), first:"taro".to_string(), age: 20};
    let person2 = Person{last:"yoshida".to_string(), first:"akira".to_string(), age: 15};
    let person3 = Person{last:"takahashi".to_string(), first:"kazumi".to_string(), age: 21};
    let person4 = Person{last:"ichiba".to_string(), first:"kumi".to_string(), age: 22};
    let person5 = Person{last:"okamoto".to_string(), first:"hajime".to_string(), age: 17};
    VECT.lock().unwrap().push(person1.clone());
    VECT.lock().unwrap().push(person2.clone());
    VECT.lock().unwrap().push(person3.clone());
    VECT.lock().unwrap().push(person4.clone());
    VECT.lock().unwrap().push(person5.clone());
    

    let mut engineers:Vec<Person> = Vec::new();
    engineers.push(person1);
    engineers.push(person2);

    for engineer in engineers {
        if let Some(remove_index) = VECT.lock().unwrap().iter().position(|x| *x == engineer){
            VECT.lock().unwrap().remove(remove_index);
        }
    }
    println!("{:?}", VECT.lock().unwrap());
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.94s
Running `target/debug/app`

処理が止まったままになる…

ちょっとコードが冗長になるが、別の関数に切り出して、削除後のデータを再度空にしたmutexに入れるという処理を行うと上手くいく。

#[tokio::main]
async fn main() {
    // mutex vectorの準備
    let mut vec: Vec<Person> = Vec::new();
    let person1 = Person{last:"yamada".to_string(), first:"taro".to_string(), age: 20};
    let person2 = Person{last:"yoshida".to_string(), first:"akira".to_string(), age: 15};
    let person3 = Person{last:"takahashi".to_string(), first:"kazumi".to_string(), age: 21};
    let person4 = Person{last:"ichiba".to_string(), first:"kumi".to_string(), age: 22};
    let person5 = Person{last:"okamoto".to_string(), first:"hajime".to_string(), age: 17};
    VECT.lock().unwrap().push(person1.clone());
    VECT.lock().unwrap().push(person2.clone());
    VECT.lock().unwrap().push(person3.clone());
    VECT.lock().unwrap().push(person4.clone());
    VECT.lock().unwrap().push(person5.clone());
    
    println!("{:?}", VECT.lock().unwrap());

    // mutex vectorから削除したい値
    let mut engineers:Vec<Person> = Vec::new();
    engineers.push(person1);
    engineers.push(person2);

    let objs = processing_mutex_vector(engineers).await;

    // 一度全て削除し、残したいデータを挿入する
    VECT.lock().unwrap().clear();
    for obj in objs {
        VECT.lock().unwrap().push(obj);
    }
    println!("{:?}", VECT.lock().unwrap());

}

async fn processing_mutex_vector(engineers:Vec<Person>) -> Vec<Person> {

    let mut binding = VECT.lock().unwrap();
    let objs = binding.deref_mut();

    for engineer in engineers {
        if let Some(remove_index) = objs.iter().position(|x| *x == engineer){
            objs.remove(remove_index);
        }
    }
    return objs.to_vec();
}

[Person { last: “yamada”, first: “taro”, age: 20 }, Person { last: “yoshida”, first: “akira”, age: 15 }, Person { last: “takahashi”, first: “kazumi”, age: 21 }, Person { last: “ichiba”, first: “kumi”, age: 22 }, Person { last: “okamoto”, first: “hajime”, age: 17 }]
[Person { last: “takahashi”, first: “kazumi”, age: 21 }, Person { last: “ichiba”, first: “kumi”, age: 22 }, Person { last: “okamoto”, first: “hajime”, age: 17 }]