簡體   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