Заполните вектор элементов структуры с помощью итерации, а не с помощью .push () по одному - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь найти элегантный способ заполнить вектор структурных элементов циклом или логикой вместо того, чтобы писать по одному .push() для каждого создаваемого мной элемента.

Элемент struct является вопросомс гораздо большим количеством полей, чем в следующем примере, и экземпляры должны быть изменяемыми, поскольку они изменяются пользовательским вводом:

struct Question {
    id: usize,
    question: String,
}

fn main() {
    //A large and growing list of questions
    let mut q0 = Question {
        id: 0,
        question: String::from("A field I fill in manually"),
    };
    //  .
    //  .
    //  .
    let mut q100 = Question {
        id: 100,
        question: String::from("Another field, each one is different"),
    };

    let total_questions: usize = 100;

    let mut w: Vec<String> = Vec::new();
    for a in 0..total_questions {
        let s = format!("q{}", a);
        w.push(s);
    }
    //w contains ["q0", "q1", ..., "q100"] but is of type std::string::String

    let mut v: Vec<&mut Question> = Vec::new();
    //Expects type struct `main::Question`

    //I would like to avoid :
    v.push(&mut q0);
    v.push(&mut q1);
    //  .
    //  .
    //  .
    v.push(&mut q100);
}

Я не уверен, что в моем примере w: Vec<String> имеет какое-либо применение.

Я изучил .collect(), но не мог понять, как использовать его в моем случае.

Я был бы рад ответить на аналогичный вопрос, если у меня есть дубликатне найден.

Редактировать: Я изменил содержимое структуры Structs, поскольку оно вводило в заблуждение. Каждая из них содержит строки, которые являются уникальными и не могут быть сгенерированы. Я также понял, что переполнение стека автоматически включает это в some_fn() функцию, когда мы на самом деле внутри main()

Ответы [ 2 ]

1 голос
/ 26 октября 2019

Проблема в том, что у вас нет какой-либо структуры данных, которая содержит Question s - у вас просто есть более 100 независимых локальных переменных - невозможно выполнить их итерацию для заполнения Vec. Вы можете исправить это, поместив все Question в Vec<Question> при их создании. Вот пример:

let mut v: Vec<Question> = vec![
    Question {
        id: 0,
        question: String::from("Q0"),
    },
    // ...
    Question {
        id: 100,
        question: String::from("Q100"),
    },
];

На самом деле, как только вы это сделаете, вам, вероятно, вообще не понадобится Vec<&mut Question>, поскольку вы можете поменять вопросы напрямую, проиндексировав v. Однако, если вам по какой-то причине нужен вектор ссылок, вы можете создать его, собрав итератор:

let v_refs: Vec<&mut Question> = v.iter_mut().collect();
0 голосов
/ 25 октября 2019

Если вы можете сгенерировать объект Question с помощью функции, вы можете использовать итератор. Здесь - это пример, который просто генерирует пронумерованные Question объекты из числового диапазона:

struct Question {
    id: usize,
    question: String,
}

fn main() {
    let v: Vec<Question> = (0..10)
        .map(|x| Question {
            id: x,
            question: "Q".to_string() + &x.to_string(),
        })
        .collect();

    for x in &v {
        println!("{}: {}", x.id, x.question);
    }
}

Здесь - это пример, где вы получаете строки измассив строк:

struct Question<'a> {
    id: usize,
    question: &'a str,
}

const QUESTIONS: [&str; 3] = ["A", "B", "C"];

fn main() {
    let v: Vec<Question> = (0..questions.len())
        .map(|x| Question {
            id: x,
            question: questions[x],
        })
        .collect();

    for x in &v {
        println!("{}: {}", x.id, x.question);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...