我遇到一些Rust代码有问题。我有一个相当简单的函数,但它会在代码中抛出错误,似乎是无关的:
use std::env::Args;
fn without_xxx(args: Args) -> Vec<String>{
let mut out: Vec<String> = vec![];
let mut xxx = false;
for arg in args{
match &arg{
"-" => xxx=true, //this line
_ => out.push(arg.to_string())
}
}
return out;
}
如果您注释掉标记的行,则不会显示错误。但是,通过这条简单的线条,它揭示了这组神秘的错误:
<anon>:7:9: 12:10 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
<anon>: 7 for arg in args{
<anon>: 8 match &arg{
<anon>: 9 "-" => xxx=true,
<anon>:10 _ => out.push(arg.to_string())
<anon>:11 }
<anon>:12 }
<anon>:7:9: 12:10 help: see the detailed explanation for E0277
<anon>:7:9: 12:10 note: `str` does not have a constant size known at compile-time
<anon>:7:9: 12:10 note: required by `core::option::Option::Some`
<anon>:7:13: 7:16 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
<anon>:7 for arg in args{
^~~
<anon>:7:13: 7:16 help: see the detailed explanation for E0277
<anon>:7:13: 7:16 note: `str` does not have a constant size known at compile-time
<anon>:7:13: 7:16 note: all local variables must have a statically known size
<anon>:7:9: 12:10 error: type mismatch resolving `<std::env::Args as core::iter::Iterator>::Item == str`:
expected struct `collections::string::String`,
found str [E0271]
<anon>: 7 for arg in args{
<anon>: 8 match &arg{
<anon>: 9 "-" => xxx=true,
<anon>:10 _ => out.push(arg.to_string())
<anon>:11 }
<anon>:12 }
<anon>:7:9: 12:10 help: see the detailed explanation for E0271
答案 0 :(得分:5)
我认为你已经阅读了有关questions的其他error,所以我只是介绍这个具体案例。
您想使用&arg[..]
代替&arg
:
fn without_xxx(args: Args) -> Vec<String> {
let mut out = vec![];
let mut xxx = false;
for arg in args {
match &arg[..] {
"-" => xxx = true,
_ => out.push(arg)
}
}
out
}
我承认错误是一个奇怪的错误。以下是我的想法:
当您执行&arg
时,您正在引用String
。 String
实施Deref<Target = str>
,这意味着他们可以参与 deref强制。
匹配组的类型为&str
。比较这两种类型时,编译器会看到您有&String
并尝试将其与&str
匹配。它会自动取消引用这两个值并应用deref强制。但是,str
不能是独立类型,因此您会收到错误。
使用&arg[..]
会触发Index
特征。这会产生&str
,因此匹配臂不会进行任何自动解除引用或强制。
此外:
output
to_string
已经是arg
,因此无需致电String
。为了好玩,这是一个使用filter_map
,collect
和普通if
的版本:
fn without_xxx(args: Args) -> Vec<String> {
let mut xxx = false;
let out = args.filter_map(|a| {
if a == "-" {
xxx = true;
None
} else {
Some(a)
}
}).collect();
// I assume you do something with `xxx` here
out
}
此可能具有性能优势,因为它可以潜在地分配向量大小的上限。
另一个版本:
fn without_xxx(args: Args) -> Vec<String> {
let mut xxx = false;
let out = args.filter(|a| {
let matched = a == "-";
xxx = xxx || matched;
!matched
}).collect();
// I assume you do something with `xxx` here
out
}