我正在学习/试验Rust,在我用这种语言找到的所有优雅中,有一个让我感到困惑并且看起来完全不合适的特点.
在进行方法调用时,Rust会自动取消引用指针.我做了一些测试来确定确切的行为:
struct X { val: i32 }
impl std::ops::Deref for X {
type Target = i32;
fn deref(&self) -> &i32 { &self.val }
}
trait M { fn m(self); }
impl M for i32 { fn m(self) { println!("i32::m()"); } }
impl M for X { fn m(self) { println!("X::m()"); } }
impl M for &X { fn m(self) { println!("&X::m()"); } }
impl M for &&X { fn m(self) { println!("&&X::m()"); } }
impl M for &&&X { …Run Code Online (Sandbox Code Playgroud) 当循环遍历一个结构片段时,我得到的值是一个引用(这很好),但是在某些情况下,必须var像(*var)在很多地方一样编写它是很烦人的.
有没有更好的方法来避免重新声明变量?
fn my_fn(slice: &[MyStruct]) {
for var in slice {
let var = *var; // <-- how to avoid this?
// Without the line above, errors in comments occur:
other_fn(var); // <-- expected struct `MyStruct`, found reference
if var != var.other {
// ^^ trait `&MyStruct: std::cmp::PartialEq<MyStruct>>` not satisfied
foo();
}
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅:实际错误输出(更加神秘).
我需要迭代一个Vec但我需要每个迭代元素的位置.我确定这已经在API中,但我看不到它.
我需要这样的东西:
fn main() {
let v = vec![1; 10];
for (pos, e) in v.iter() {
// do something here
}
}
Run Code Online (Sandbox Code Playgroud) 我试图筛选Vec<Vocabulary>这里Vocabulary是一个自定义的struct,它本身包含一个struct VocabularyMetadata和Vec<Word>:
#[derive(Serialize, Deserialize)]
pub struct Vocabulary {
pub metadata: VocabularyMetadata,
pub words: Vec<Word>
}
Run Code Online (Sandbox Code Playgroud)
这用于处理Web应用程序中的路由,其中路由如下所示:/word/<vocabulary_id>/<word_id>.
这里是我当前的代码试图filter在Vec<Vocabulary>:
let the_vocabulary: Vec<Vocabulary> = vocabulary_context.vocabularies.iter()
.filter(|voc| voc.metadata.identifier == vocabulary_id)
.collect::<Vec<Vocabulary>>();
Run Code Online (Sandbox Code Playgroud)
这不起作用.我得到的错误是:
the trait `std::iter::FromIterator<&app_structs::Vocabulary>` is not implemented for `std::vec::Vec<app_structs::Vocabulary>` [E0277]
Run Code Online (Sandbox Code Playgroud)
我不知道如何实施任何FromIterator,也不知道为什么这是必要的.在同一个Web应用程序中的另一个路径中,我执行以下相同的文件,其工作原理:
let result: Vec<String> = vocabulary_context.vocabularies.iter()
.filter(|voc| voc.metadata.identifier.as_str().contains(vocabulary_id))
.map(encode_to_string)
.collect::<Vec<String>>();
result.join("\n\n") // returning
Run Code Online (Sandbox Code Playgroud)
所以它似乎String实现了FromIterator.
但是,我没有得到,为什么我不能简单地Vec从the filter或collect方法中获取元素. …
我的函数返回Vec对元组的引用,但我需要一个Vec元组:
use std::collections::HashSet;
fn main() {
let maxs: HashSet<(usize, usize)> = HashSet::new();
let mins: HashSet<(usize, usize)> = HashSet::new();
let intersection = maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>();
}
Run Code Online (Sandbox Code Playgroud)
我该如何进行转换?
错误:
19 | maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
|
= note: expected type `std::vec::Vec<(usize, usize)>`
found type `std::vec::Vec<&(usize, usize)>`
Run Code Online (Sandbox Code Playgroud)
我正在使用for循环来进行转换,但我不喜欢它,我认为应该有一种模式惯用的方式:
for t in maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>().iter() {
output.push(**t);
}
Run Code Online (Sandbox Code Playgroud) 我在使用Iterator'sflat_map函数时遇到了困难,我不太确定如何理解和解决这个编译器错误。
我通过序列化两个结构将文件路径列表 flat_mapping 成两个字符串:
let body: Vec<String> = read_dir(query.to_string())
.iter()
.enumerate()
.flat_map(|(i, path)| {
let mut body: Vec<String> = Vec::with_capacity(2);
let entry = Entry { i };
body.push(serde_json::to_string(&entry).unwrap());
let record = parse_into_record(path.to_string()).unwrap();
body.push(serde_json::to_string(&record).unwrap());
body.iter()
})
.collect();
Run Code Online (Sandbox Code Playgroud)
error[E0277]: a value of type `std::vec::Vec<std::string::String>` cannot be built from an iterator over elements of type `&std::string::String`
--> src/main.rs:275:10
|
275 | .collect();
| ^^^^^^^ value of type `std::vec::Vec<std::string::String>` cannot be built from `std::iter::Iterator<Item=&std::string::String>`
|
= help: the trait `std::iter::FromIterator<&std::string::String>` …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现可以无限迭代的结构。认为它是自然数。我有一个局限性:它不能实现Copy特征,因为结构包含一个String字段。
我还实现了一个Iterable特征及其唯一成员fn next(&mut self) -> Option<Self::Item>。
当前,我有以下代码可以迭代结构的前10个项目:
let mut counter = 0;
let mut game:Option<Game> = Game::new(¶m);
loop {
println!("{:?}", game);
game = g.next();
counter = counter + 1;
if counter > 10 { break; }
}
Run Code Online (Sandbox Code Playgroud)
我想让用户crate能够使用for in构造对我的结构进行迭代,如下所示:
for next_game in game {
println!("{:?}", next_game);
}
Run Code Online (Sandbox Code Playgroud)
有可能吗?我该如何实现?如何使我的代码更好,以及与我的结构有什么关系?
迭代器实现:
pub struct Game {
/// The game hash
pub hash: Vec<u8>
}
impl Iterator for Game {
type Item …Run Code Online (Sandbox Code Playgroud) 假设我们有一个可以克隆的某种类型的向量
let foo_vec = vec![clonable_item_1, clonable_item_2, ...];
Run Code Online (Sandbox Code Playgroud)
如何判断是否使用.clone()以及.cloned()何时迭代?
foo_vec.iter().cloned()...
// vs
foo_vec.clone().iter()...
Run Code Online (Sandbox Code Playgroud)
我找不到任何关于两者之间差异的文字。有什么不同?
为什么这三个print_max功能都会起作用?哪一种是最佳实践?是 的for number in number_list快捷方式吗for number in number_list.iter()?
fn main() {
let number_list = vec![34, 50, 25, 100, 65];
print_max_1(&number_list);
print_max_2(&number_list);
print_max_3(&number_list);
}
fn print_max_1(number_list: &[u16]) {
let mut largest = &number_list[0]; // borrow the first number
for number in number_list.iter() { // borrowing?
if number > largest {
largest = number;
}
}
println!("The largest number is {}", largest);
}
fn print_max_2(number_list: &[u16]) {
let mut largest = &number_list[0]; // borrow the first …Run Code Online (Sandbox Code Playgroud) 我对此感到困惑:
use itertools::Itertools; // 0.10.0
fn main() {
let combos = ["a", "b", "c"].iter().combinations(2).collect::<Vec<_>>();
println!("{:#?}", combos[0].join(""));
}
Run Code Online (Sandbox Code Playgroud)
error[E0599]: the method `join` exists for struct `Vec<&&str>`, but its trait bounds were not satisfied
--> src/main.rs:5:33
|
5 | println!("{:#?}", combos[0].join(""));
| ^^^^ method cannot be called on `Vec<&&str>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`Vec<&&str>: Iterator`
which is required by `Vec<&&str>: Itertools`
`<[&&str] as Join<_>>::Output = _`
`[&&str]: Iterator`
which is required …Run Code Online (Sandbox Code Playgroud)