虽然向量最适合程序编程,但我想map在它们上使用函数.以下代码段有效:
fn map<A, B>(u: &Vec<A>, f: &Fn(&A) -> B) -> Vec<B> {
let mut res: Vec<B> = Vec::with_capacity(u.len());
for x in u.iter() {
res.push(f(x));
}
res
}
fn f(x: &i32) -> i32 {
*x + 1
}
fn main() {
let u = vec![1, 2, 3];
let v = map(&u, &f);
println!("{} {} {}", v[0], v[1], v[2]);
}
Run Code Online (Sandbox Code Playgroud)
为什么标准库中没有这样的功能?(以及std::collections::LinkedList).有没有其他方法来处理它?
我有一个带字段的结构:
struct A {
field: SomeType,
}
Run Code Online (Sandbox Code Playgroud)
给定a &mut A,如何移动值field并交换新值?
fn foo(a: &mut A) {
let mut my_local_var = a.field;
a.field = SomeType::new();
// ...
// do things with my_local_var
// some operations may modify the NEW field's value as well.
}
Run Code Online (Sandbox Code Playgroud)
最终目标相当于一项get_and_set()行动.在这种情况下,我并不担心并发性.
我想在不使用任何克隆的情况下将旧变体的字段移动到新变体时更新枚举变体:
enum X {
X1(String),
X2(String),
}
fn increment_x(x: &mut X) {
*x = match *x {
X::X1(s) => X::X2(s),
X::X2(s) => X::X1(s),
}
}
Run Code Online (Sandbox Code Playgroud)
这并不工作,因为我们不能移动s的&mut X.
请不要建议实现enum X { X1, X2 }和使用struct S { variant: X, str: String }等等.这是一个简化的例子,想象在变体中有许多其他字段,并希望将一个字段从一个变量移动到另一个变体.
我想收集结构的更改并立即应用它们.基本大纲如下所示:
enum SomeEnum {
Foo,
Bar,
}
struct SomeStruct {
attrib: SomeEnum,
next_attrib: Option<SomeEnum>,
}
impl SomeStruct {
pub fn apply_changes(&mut self) {
if let Some(se) = self.next_attrib {
self.attrib = se;
}
self.next_attrib = None;
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生以下编译器错误:
Run Code Online (Sandbox Code Playgroud)error[E0507]: cannot move out of borrowed content --> src/lib.rs:13:27 | 13 | if let Some(se) = self.next_attrib { | -- ^^^^ cannot move out of borrowed content | | | hint: to prevent move, use `ref se` or `ref mut se` …
我想在可变借入中替换一个值; 将其中的一部分移动到新值中:
enum Foo<T> {
Bar(T),
Baz(T),
}
impl<T> Foo<T> {
fn switch(&mut self) {
*self = match self {
&mut Foo::Bar(val) => Foo::Baz(val),
&mut Foo::Baz(val) => Foo::Bar(val),
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码不起作用,并且可以理解的是,将值移出会self破坏它的完整性.但由于之后立即删除了该值,我(如果不是编译器)可以保证它的安全性.
有没有办法实现这个目标?我觉得这是一个不安全代码的工作,但我不确定这是如何工作的.
我正在尝试使用此签名编写一个函数,而不使用clone()或分配新的向量:
fn mapVec(f: Fn(T) -> T, x: Vec<T>) -> Vec<T>
Run Code Online (Sandbox Code Playgroud)
在我看来,这似乎是可行的。对于中的每个元素x,我们将其传递给f,并f获得所有权。然后,我们产生一个返回值,然后,作为f已传递值的所有权,如果有必要,它将销毁它。然后,我们将返回值放回向量中。拥有的所有权后x,我们可以对其进行修改,然后将其返回给调用方。
我的尝试如下:
for e in x.iter_mut() {
*e = f(e);
}
return x;
Run Code Online (Sandbox Code Playgroud)
但不幸的是f期望一个T,而不是一个&mut T。
我不想将其签名更改mapVec为例如使用可变函数,如果可能的话,我希望它看起来像是一个外部纯函数,只是利用内部的变异,因为我们可以摆脱它,因为调用者已将对象的所有权传递给我们。