繁体   English   中英

如何从Rust函数返回向量元素?

[英]How do I return a vector element from a Rust function?

我想返回一个向量的元素:

struct EntryOne {
    pub name: String,
    pub value: Option<String>,
}

struct TestVec {}

impl TestVec {
    pub fn new() -> TestVec {
        TestVec {}
    }

    pub fn findAll(&self) -> Vec<EntryOne> {
        let mut ret = Vec::new();
        ret.push(EntryOne {
            name: "foo".to_string(),
            value: Some("FooVal".to_string()),
        });
        ret.push(EntryOne {
            name: "foo2".to_string(),
            value: Some("FooVal2".to_string()),
        });
        ret.push(EntryOne {
            name: "foo3".to_string(),
            value: None,
        });
        ret.push(EntryOne {
            name: "foo4".to_string(),
            value: Some("FooVal4".to_string()),
        });

        ret
    }

    pub fn findOne(&self) -> Option<EntryOne> {
        let mut list = &self.findAll();

        if list.len() > 0 {
            println!("{} elements found", list.len());
            list.first()
        } else {
            None
        }
    }
}

fn main() {
    let test = TestVec::new();
    test.findAll();
    test.findOne();
}

游乐场

我总是得到这个错误:

error[E0308]: mismatched types
  --> src/main.rs:40:13
   |
35 |     pub fn findOne(&self) -> Option<EntryOne> {
   |                              ---------------- expected `std::option::Option<EntryOne>` because of return type
...
40 |             list.first()
   |             ^^^^^^^^^^^^ expected struct `EntryOne`, found &EntryOne
   |
   = note: expected type `std::option::Option<EntryOne>`
              found type `std::option::Option<&EntryOne>`

如何返回元素?

看看Vec::first的签名:

fn first(&self) -> Option<&T>

给定对向量的引用,如果有向量,它将返回对第一个项的引用,否则返回None 这意味着包含值的向量必须比返回值更长,否则引用将指向未定义的内存。

主要有两种途径:

  1. 如果无法更改向量,则需要复制数据结构。 最简单的方法是使用#[derive(Clone)]注释结构。 然后,你可以调用Option::cloned上的结果first

  2. 如果您可以更改向量,则可以从中删除第一个值并将其返回。 有很多方法可以做到这一点,但最短的代码是使用drain迭代器。

#[derive(Debug, Clone)]
struct EntryOne {
    name: String,
    value: Option<String>,
}

fn find_all() -> Vec<EntryOne> {
    vec![
        EntryOne {
            name: "foo".to_string(),
            value: Some("FooVal".to_string()),
        },
        EntryOne {
            name: "foo2".to_string(),
            value: Some("FooVal2".to_string()),
        },
        EntryOne {
            name: "foo3".to_string(),
            value: None,
        },
        EntryOne {
            name: "foo4".to_string(),
            value: Some("FooVal4".to_string()),
        },
    ]
}

fn find_one_by_clone() -> Option<EntryOne> {
    find_all().first().cloned()
}

fn find_one_by_drain() -> Option<EntryOne> {
    let mut all = find_all();
    let mut i = all.drain(0..1);
    i.next()
}

fn main() {
    println!("{:?}", find_one_by_clone());
    println!("{:?}", find_one_by_drain());
}

其他变化:

  1. 如果没有状态,就不需要TestVec ; 只是做功能。
  2. Rust样式是方法和变量名称的snake_case
  3. 使用vec! 在提供所有元素时构造向量。
  4. 导出Debug以便您可以打印该值。

如果你想总是得到最后一个元素,你可以使用pop

fn find_one_by_pop() -> Option<EntryOne> {
    find_all().pop()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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