【问题标题】:Can't use Vec two times and I can't borrow it instead无法使用 Vec 两次,我不能借用它
【发布时间】:2018-11-12 21:23:25
【问题描述】:

我尝试实现 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>`

帮助消息说我应该删除借用,因为类型不匹配,但删除后仍然出现错误,因为值已被移动。

【问题讨论】:

  • 比起String,你最好使用&amp;[u8],因为你不需要unicode。
  • @PeterHall 感谢您的建议。

标签: vector rust move-semantics borrowing


【解决方案1】:

您已将类型声明为Vec&lt;Vec&lt;String&gt;&gt;,但您正试图在其中存储一个引用。

当您删除引用时,您会收到不同的错误,因为 push 拥有该值的所有权,因此无法再使用原始变量。但是您随后尝试在后续循环中使用它。简单的解决方法是在循环中声明变量inside,因此每次都是一个新变量:

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);
}

请注意,您不需要很多类型注释,尤其是在局部函数变量上。编译器可以推断它们,这使得代码更清晰。

【讨论】:

  • 我没想到!!非常感谢。我想我会改用字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-24
  • 1970-01-01
相关资源
最近更新 更多