【问题标题】:Function signatures to reduce borrow checker problems减少借用检查器问题的函数签名
【发布时间】:2021-07-16 15:59:25
【问题描述】:

我正在学习 Rust,想知道如何为某个问题建模。假设我有一些具有多个属性的人被建模为一个结构。

struct Person {
        available_days: Vec<bool> // [0]=Monday .. [6]=Sunday
        possible_roles: Vec<Role>
        preferred_role: Role
        in_group: bool
        ... (quite a few more)

我想建立小组,但必须满足要求。例如。每个组中必须有一定数量的角色,它们必须在同一天可用,等等。我试过这个签名:

fn build_group(avail_persons: &mut Vec<Person>) -> Option<Group> {...}

此签名的想法是获取对预选人员向量的引用,并尝试找到一个好的组设置。

调用 build_group 的函数会做这样的事情:

let mut avail_day = persons
        .iter()
        .filter(|d|d.available_days[0] == 1) // all persons avialable on Monday
        .collect::Vec<&Person>>(); 

这会创建一个Vec&lt;&amp;Person&gt;,而我无法创建一个Vec&lt;Person&gt;(缺少复制特征)。 一个解决方案是将 build_group 的签名更改为 Vec&lt;&amp;Person&gt; 但这意味着我在更改人员时遇到了困难,例如。 G。 person.in_group = 真。更改为 Vec 后,我经常遇到借用检查器的问题。

我的印象是我从根本上以非生锈友好的方式对问题进行建模。

有什么建议吗?也许是处理此类问题的 github 存储库的链接。无论如何,我想从有经验的人那里阅读 Rust 代码。我希望我能够足够好地描述这个问题。

【问题讨论】:

  • persons的类型是什么?为什么build_group() 接受对Vec&lt;Person&gt; 的可变引用,它是否会改变Vec 的内容?能提供更完整的sn-p吗?
  • 使用原始 vec 中人员的索引对组进行建模可能更容易。例如:let avail_day = persons.iter().enumerate().filter_map (|(i, p)| if p.available_days[0] { Some (i) } else { None }).collect::&lt;Vec&lt;usize&gt;&gt;();
  • 如果可以复制Person,则可以克隆实例以添加到Group,而不会出现借用检查器问题。但是,如果Person 的状态需要在其他地方更新并且可以作为单个实例访问,则您需要研究智能指针以实现可变共享访问。这些类包括用于单线程访问的RcRefCell

标签: rust


【解决方案1】:

如果 personsVec 并且在过滤后您不再需要它,您可以这样做:

let mut avail_day = persons.retain(|d| d.available_days[0] == 1); // all persons avialable on Monday

retain"只保留谓词指定的元素"。

如果您需要使用另一个Persons,您可以将Vec 分成两个集合:

let (mut avail_day, unavail_day): (Vec<Person>, Vec<Person>) = persons
        .into_iter()
      // ^^^^^ note the "into" here
        .partition(|d| d.available_days[0] == 1); // all persons avialable on Monday

into_iter 通过值而不是通过引用获取Vec,并允许您再次将其收集到值中。

顺便说一句,在 Rust 中,如果您通过引用来获取参数,那么最好使用切片而不是 Vec,即签名应该是

fn build_group(avail_persons: &mut [Person]) -> Option<Group> {...}

通过这种方式,您可以传入任何可以转换为切片的内容(例如Vecs)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多