gpt4 book ai didi

rust - 不可变值仍在移动

转载 作者:行者123 更新时间:2023-12-03 11:24:31 25 4
gpt4 key购买 nike

我无法编译这个函数:

/// Return a String with all characters masked as '#' except the last 4.
fn maskify(cc: &str) -> String {
let chars = cc.to_string().chars();
chars
.enumerate()
.map(|(i, c)| {
if i > chars.count() - 4 { '#' } else { c }
})
.collect()
}
目前的错误是:
error[E0507]: cannot move out of `chars`, a captured variable in an `FnMut` closure
--> src/lib.rs:7:21
|
3 | let chars = cc.to_string().chars();
| ----- captured outer variable
...
7 | if i > &chars.count() - 4 { '#' } else { c }
| ^^^^^ move occurs because `chars` has type `std::str::Chars<'_>`, which does not implement the `Copy` trait

error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:3:17
|
3 | let chars = cc.to_string().chars();
| ^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
4 | chars
| ----- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value

error[E0382]: use of moved value: `chars`
--> src/lib.rs:6:14
|
3 | let chars = cc.to_string().chars();
| ----- move occurs because `chars` has type `std::str::Chars<'_>`, which does not implement the `Copy` trait
4 | chars
| ----- value moved here
5 | .enumerate()
6 | .map(|(i, c)| {
| ^^^^^^^^ value used here after move
7 | if i > &chars.count() - 4 { '#' } else { c }
| ----- use occurs due to use in closure
我认为错误的来源是 chars是一个迭代器,所以它会发生变化,从而无法在闭包中借用,但即使我尝试声明一个局部变量(例如 let count = chars.count() ),我仍然会遇到借用错误。
我试过用 & 取消引用它,但这也不起作用。

最佳答案

这里问题的关键是Char::count()消费 self .即使声明了局部变量,也不能使用 chars在您将所有权移至 count 后功能:

fn maskify(cc: &str) {
let chars = cc.to_string().chars();
// ^^^^^ move occurs here
let count = chars.count();
// ^^^^^^ `chars` moved because `count` consumes self
let _ = chars.enumerate();
// ^^^^^ value used here after move - *this is not allowed*
}
您可以通过创建一个新的迭代器并使用它来获取 count 来解决这个问题。 :
fn maskify(cc: &str) -> String {
let chars = cc.chars();
let count = cc.chars().count();
// ^^^ create and consume a new iterator over cc
chars
.enumerate()
.map(|(i, c)| {
if i < count - 4 { '#' } else { c }
})
.collect()
}

fn main() {
assert_eq!(maskify("abcd1234"), "####1234");
}
或者您可以使用 .len() 获取字符串的长度:
fn maskify(cc: &str) -> String {
let chars = cc.chars();
chars
.enumerate()
.map(|(i, c)| {
if i < cc.len() - 4 { '#' } else { c }
})
.collect()
}

fn main() {
assert_eq!(maskify("abcd1234"), "####1234");
}
请注意 str.len()只能处理 ascii 而 .chars().count()可以处理完整的utf8。

关于rust - 不可变值仍在移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65173868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com