Reputation: 552
I attempted to implement the Rosetta Code password generator:
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 won't allow me to use either borrowed value or direct value:
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>`
The help message says I should remove the borrow because of type mismatch but it's still got an error after removing it because the value has been moved.
Upvotes: 2
Views: 554
Reputation: 58705
You've declared a type to be Vec<Vec<String>>
, but you're trying to store a reference inside it.
When you remove the reference, you're getting a different error because push
takes ownership of the value, so the original variable can no longer be used. But you then try to use it in the subsequent loop. The easy fix is to declare the variable inside the loop, so it is a new variable each time:
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);
}
Note that you don't need a lot of the type annotations, especially on local function variables. The compiler can infer them, which makes the code a lot cleaner.
Upvotes: 3