Не могу использовать Vec два раза, и я не могу взять его взамен - PullRequest
0 голосов
/ 03 июня 2018

Я попытался реализовать генератор паролей Rosetta Code:

extern crate rand;

use rand::prelude::*;

fn main() {
    println!("Hello, world!");
    let p = generate_password(12, 5);
    for i in p.iter() {
        println!("{:?}", i);
    }
}

fn generate_password(length: i32, number: i32) -> Vec<Vec<String>> {
    let lowercase = "abcdefghijklmnopqrstuvwxyz";
    let uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let listnumber = "0123456789";
    let other = "!\\\"#$%&'()*+,-./:;<=>?@[]^_{|}~";
    let all: Vec<char> = String::from(format!("{}{}{}{}", lowercase, uppercase, listnumber, other))
        .chars()
        .collect();
    let mut password: Vec<String> = Vec::new();
    let mut password_list: Vec<Vec<String>> = Vec::new();
    for num in 1..number {
        for l in 1..length {
            password.push(String::from(thread_rng().choose(&all).unwrap().to_string()));
        }
        password_list.push(&password);
    }
    return password_list;
}

Rust не позволит мне использовать заимствованное или прямое значение:

error[E0308]: mismatched types
  --> src/main.rs:26:28
   |
26 |         password_list.push(&password);
   |                            ^^^^^^^^^
   |                            |
   |                            expected struct `std::vec::Vec`, found reference
   |                            help: consider removing the borrow: `password`
   |
   = note: expected type `std::vec::Vec<std::string::String>`
              found type `&std::vec::Vec<std::string::String>`

В справочном сообщении говоритсяЯ должен удалить заимствование из-за несоответствия типов, но после удаления все равно возникает ошибка, поскольку значение было перемещено.

1 Ответ

0 голосов
/ 03 июня 2018

Вы объявили тип Vec<Vec<String>>, но вы пытаетесь сохранить ссылку внутри него.

При удалении ссылки вы получаете другую ошибку, потому что pushстановится владельцем значения, поэтому исходная переменная больше не может быть использована.Но затем вы попытаетесь использовать его в последующем цикле.Простое решение - объявить переменную внутри цикла, поэтому она каждый раз является новой переменной:

let mut password_list = Vec::new();
for num in 1..number {
    let mut password = Vec::new();
    for l in 1..length {
        password.push(String::from(thread_rng().choose(&all).unwrap().to_string()));
    }
    password_list.push(password);
}

Обратите внимание, что вам не нужно много аннотаций типов,особенно на локальные переменные функции.Компилятор может вывести их, что делает код намного чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...