gpt4 book ai didi

rust - 在Struct Vec中找到Struct,然后在Rust中对该Struct执行Trait功能的惯用方式

转载 作者:行者123 更新时间:2023-12-03 11:34:45 25 4
gpt4 key购买 nike

在我的项目中,我经常遍历结构的向量以通过某个字段值找到一个对象,然后对该对象使用一些特征函数:

pub struct Person{
name: String,
age: u32,
id: u32,
}

impl Person{
pub fn new(name: String, id_num: u32, age: u32)->Self{
let p = Person{
name: name,
id: id_num,
age: age,
};
p
}
}

trait PersonTrait{
fn printname();
fn get_name()->String;
fn get_age()->u32;
fn set_age(age: u32);
}


impl PersonTrait for Person{
fn printname(){
dbg!(self.name)
}
fn get_name()->String{
self.name
}
fn get_id()->u32{
self.id;
}
fn set_age(age: u32){
self.age = age;
}
}


fn main(){
let my_people = vec![Person::new("Rakim".to_string(), 1, 56), Person::new("Ghostface".to_string(), 2, 56), Person::new("RZA".to_string(), 3, 56)];
//frequently repeating this pattern of finding struct in array of structs, then doing something to that found struct

for person in my_people.clone(){
if person.get_id() == 1 {
person.set_age(100);
}
}

for person in my_people.clone(){
if person.get_id() == "Rakim".to_string(){
person.printname();
}
}

}
所以我在这里使用的一般模式是:
for x in my_objects{
if x.id() == some_id{
x.do_some_trait_function()
}
}

我想创建一个更通用的函数来简化此语法,例如:
//not sure what the correct syntax would be here, or how you might pass a trait function as an argument
fn find_then_do_trait_function(obj_list: Vec<Person>, id: u32, trait_function: my_trait_function()){
for x in obj_list(){
if x.get_id() == id {
//use my trait function on x
}
}
}

我该怎么办?我知道我可以为每个特征函数创建一个 enum,然后为该枚举创建 match,但这似乎也很冗长。

最佳答案

特征功能没有什么独特之处。您已经确定了一个非常常见的模式,可以将其分为两部分:我们要过滤向量,然后对每个匹配的元素执行一些操作。我们可以定义一个函数,该函数需要两个闭包参数来为我们执行此操作。

fn search_and_call<T>(obj_list: &mut Vec<T>,
mut condition: impl FnMut(&mut T) -> bool,
mut func: impl FnMut(&mut T) -> ()) {
for x in obj_list {
if condition(x) {
func(x);
}
}
}
func可以是任何闭包。该闭包可能会调用特征函数,或者可能会打印到屏幕上,或者执行任何其他操作。上面函数的作者不必关心;就我们而言,都是一样的。用法示例:
let mut v = vec!(1, 2, 3, 4);
search_and_call(&mut v, |x| *x % 2 == 0, |x| println!("{}", *x));
但是,值得注意的是,Rust出色的 Iterator trait定义了很多有用的函数,我们甚至可以在不触及 for循环的情况下免费获得此行为。
let mut v = vec!(1, 2, 3, 4);
v.iter().filter(|x| *x % 2 == 0).for_each(|x| println!("{}", *x));
.iter()在我们的向量上获得一个迭代器, .filter(...)产生一个新的迭代器,该迭代器根据我们的条件选择某些元素,并且 .for_each(...)对所有保留在过滤器之后的元素调用一个函数。

关于rust - 在Struct Vec中找到Struct,然后在Rust中对该Struct执行Trait功能的惯用方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65855097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com