Rust 私有函数在尝试返回值元组时抛出错误

Rust private function throws error when trying to return tuple of values

提问人:Abe Hoffman 提问时间:1/14/2023 最后编辑:cafce25Abe Hoffman 更新时间:1/14/2023 访问量:56

问:

我有一个函数,我试图从中返回一个值元组:

fn get_two_bytes(data: &[u8]) -> (Vec<(u8, u8)>, BTreeSet<(u8, u8)>) {
    let two_byte_vec = data
        .chunks(2)
        .map(|x| (x[0], x[1]))
        .collect::<Vec<_>>();

    let mut two_byte_set : BTreeSet<&(u8, u8)> = BTreeSet::new();
    for n in &two_byte_vec {
        two_byte_set.insert(n);
    }

    return (two_byte_vec, two_byte_set);
}

将生成此错误:

error[E0308]: mismatched types
  --> src/lib.rs:13:27
   |
13 |     return (two_byte_vec, two_byte_set);
   |                           ^^^^^^^^^^^^ expected tuple, found `&(u8, u8)`
   |
   = note: expected struct `BTreeSet<(u8, u8)>`
              found struct `BTreeSet<&(u8, u8)>`

我显然不想返回 - 我想将所有权从函数中转移出来。如何让这两个变量正确返回?&two_byte_set

Rust 元组 归还 所有权

评论

1赞 Ivan C 1/14/2023
此处的错误消息具有误导性。它谈论的是 BTreeMap 所持有的类型。即 &(u8, u8)。只需在插入地图之前 deref n 并从two_byte_set中删除类型注记
0赞 cafce25 1/14/2023
@IvanC错误没有误导性,只是被截断了,这就是为什么您应该始终阅读并提供完整的错误消息,而不仅仅是其中的一行。
0赞 Ivan C 1/14/2023
我看到@ekuber讨论过关于改进 Mastodon 上的这个确切错误消息的讨论,大多数人都同意措辞令人困惑。

答:

0赞 Silvio Mayolo 1/14/2023 #1

由于您借用了向量在循环中进行迭代,因此该循环中的类型为 。幸运的是,元组是可以克隆的,所以只需将它们克隆到你的集合中即可。forn&(u8, u8)u8

let mut two_byte_set : BTreeSet<(u8, u8)> = BTreeSet::new();
for n in &two_byte_vec {
    two_byte_set.insert(n.to_owned());
}
1赞 Ivan C 1/14/2023 #2

此处的错误消息具有误导性。

它谈论的是持有的类型,而不是你承诺 Int 函数签名。由于 是 ,元组也是 ,这意味着您可以在插入到映射中之前先 deref 并从中删除类型注解。BTreeMap&(u8, u8)(u8, u8)u8Copy(u8, u8)Copyntwo_byte_set

use std::collections::BTreeSet;

fn get_two_bytes(data: &[u8]) -> (Vec<(u8, u8)>, BTreeSet<(u8, u8)>) {
    let two_byte_vec = data.chunks(2).map(|x| (x[0], x[1])).collect::<Vec<_>>();

    let mut two_byte_set = BTreeSet::new();
    for &n in &two_byte_vec {
        two_byte_set.insert(n);
    }

    (two_byte_vec, two_byte_set);
}

评论

2赞 Ivan C 1/14/2023
我认为有必要澄清一下,这里不是借用,而是一种匹配和取消引用引用的模式。&n
0赞 user3070377 1/14/2023
@IvanC,很好的通知!我曾经在这样的上下文中编写 two_byte_set.insert(*n)。
0赞 Abe Hoffman 1/14/2023
引用的模式匹配和取消引用(特别是在声明时)让我感到困惑。这奏效了!我也希望有不同的 stracktrace 错误。感谢@IvanC的回答!n