相关疑难解决方法(0)

为什么这个可变借用超出了它的范围?

在我期望可变借用结束之后,我遇到了关于同时使用可变和不可变借用的令人困惑的错误。我对类似问题(1 , 2 , 3 , 4 , 5)进行了大量研究,这让我相信我的问题与词法生命周期有关(尽管打开 NLL 功能并每晚编译并没有) t 改变结果),我只是不知道是什么;我的情况似乎不适合其他问题的任何场景。

pub enum Chain<'a> {
    Root {
        value: String,
    },
    Child {
        parent: &'a mut Chain<'a>,
    },
}

impl Chain<'_> {
    pub fn get(&self) -> &String {
        match self {
            Chain::Root { ref value } => value,
            Chain::Child { ref parent } => parent.get(),
        }
    }

    pub fn get_mut(&mut self) -> &mut String {
        match self {
            Chain::Root { ref mut value } => …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

11
推荐指数
1
解决办法
476
查看次数

为什么可变引用没有移到这里?

我的印象是可变引用(即&mut T)总是被移动.这是完全合理的,因为它们允许独占的可变访问.在下面的代码中,我为另一个可变引用分配了一个可变引用,并移动了原始引用.结果我不能再使用原件了:

let mut value = 900;
let r_original = &mut value;
let r_new = r_original;
*r_original; // error: use of moved value *r_original
Run Code Online (Sandbox Code Playgroud)

如果我有这样的功能:

fn make_move(_: &mut i32) {
}
Run Code Online (Sandbox Code Playgroud)

并修改我的原始示例,如下所示:

let mut value = 900;
let r_original = &mut value;
make_move(r_original);
*r_original; // no complain
Run Code Online (Sandbox Code Playgroud)

我期望r_originalmake_move用它调用函数时移动可变引用.然而,这不会发生.我仍然可以在通话后使用参考.

如果我使用通用函数make_move_gen:

fn make_move_gen<T>(_: T) {
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

let mut value = 900;
let r_original = &mut value;
make_move_gen(r_original);
*r_original; // error: use of moved …
Run Code Online (Sandbox Code Playgroud)

move-semantics rust

10
推荐指数
2
解决办法
888
查看次数

生命周期和对包含引用的对象的引用

假设我有一个带有引用的结构,另一个带有该结构引用的结构,如下所示:

struct Image<'a> {
    pixel_data: &'a mut Vec<u8>,
    size: (i32, i32),
}

struct SubImage<'a> {
    image: &'a mut Image<'a>,
    offset: (i32, i32),
    size: (i32, i32),
}
Run Code Online (Sandbox Code Playgroud)

结构具有几乎相同的接口,不同之处在于SubImage在转发到所包含的Image引用的相应功能之前基于其偏移调整位置参数.我希望这些结构大多可以互换,但我似乎无法弄清楚如何让生命正确.最初,我只是在使用Image,并且可以简单地传递对象,而不会使用终身说明符:

fn main() {
    let mut pixel_data: Vec<u8> = Vec::new();
    let mut image = Image::new(&mut pixel_data, (1280, 720));
    render(&mut image);
}

fn render(image: &mut Image) {
    image.rect_fill(0, 0, 10, 10);
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了SubImage,并希望做这样的事情:

fn render2(image: &mut Image) {
    let mut sub = SubImage {
        image: image,           // …
Run Code Online (Sandbox Code Playgroud)

reference lifetime rust

7
推荐指数
1
解决办法
197
查看次数

如何修改作为函数参数的切片?

参数可以传递给函数并修改:

fn set_42(int: &mut i32) {
    *int += 42;
}

fn main() {
    let mut int = 0;
    set_42(&mut int);
    println!("{:?}", int);
}
Run Code Online (Sandbox Code Playgroud)

输出:

42
Run Code Online (Sandbox Code Playgroud)

天真地改变代码以使用切片失败了一大堆错误:

fn pop_front(slice: &mut [i32]) {
    *slice = &{slice}[1..];
}

fn main() {
    let mut slice = &[0, 1, 2, 3][..];
    pop_front(&mut slice);
    println!("{:?}", slice);
}
Run Code Online (Sandbox Code Playgroud)

输出:

<anon>:2:14: 2:27 error: mismatched types:
 expected `[i32]`,
    found `&[i32]`
(expected slice,
    found &-ptr) [E0308]
<anon>:2     *slice = &{slice}[1..];
                      ^~~~~~~~~~~~~
<anon>:2:14: 2:27 help: see the detailed explanation …
Run Code Online (Sandbox Code Playgroud)

rust

6
推荐指数
2
解决办法
1591
查看次数

当外部生命周期不同时,为什么我不能将一个引用的引用取消引用分配给另一个引用?

我想编写以下函数:

fn foo<'a, 'b, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) {
    *rr1 = *rr2;
}
Run Code Online (Sandbox Code Playgroud)

但是编译器抱怨:

fn foo<'a, 'b, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut &'c mut u32) {
    *rr1 = *rr2;
}
Run Code Online (Sandbox Code Playgroud)

我对 Rust 生命周期的心智模型不同意代码是错误的。我读的类型rr2为“具有寿命的引用'b与寿命的参考'c到一个u32”。因此,当我提领rr2,我与寿命引用'cu32。这应该可以安全地存储在*rr1具有相同类型的 中。

如果我需要它的'b寿命'c,它的工作原理:

fn foo<'a, 'b: 'c, 'c>(rr1: &'a mut &'c mut u32, rr2: &'b mut …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

5
推荐指数
1
解决办法
115
查看次数

为什么HashMap :: get_mut比HashMap更挑剔:: get关于生命周期?

我有一个参考struct Foo<'a>包装&'a str.我想HashMapFoos作为键来填充.这是一段代码(在操场上打开):

use std::collections::HashMap;

#[derive(PartialEq, Eq, Hash)]
struct Foo<'a> {
    txt: &'a str,
}

fn main() {
    let a = "hello".to_string();
    let a2 = Foo { txt: &a };
    let b = "hello".to_string();
    let b2 = Foo { txt: &b };

    let mut hm = HashMap::<Foo, u32>::new();

    hm.insert(a2, 42);
    println!("=== {:?}", hm.get(&b2));     // prints Some(42)
    println!("=== {:?}", hm.get_mut(&b2)); // prints Some(42)

    {
        let c = "hello".to_string();
        let c2 = …
Run Code Online (Sandbox Code Playgroud)

lifetime rust

4
推荐指数
1
解决办法
216
查看次数

Rust中Box类型的协方差

在阅读Nomicon的子类型章节之后,我就无法将类型参数的协方差包住。特别是对于Box<T>类型,它被描述为:T is covariant

但是,如果我编写此代码:

trait A {}
trait B: A {}

struct C;
impl A for C {}
impl B for C {}

fn foo(v: Box<A>) {}

fn main() {
    let c = C;
    let b: Box<B> = Box::new(c);
    foo(b);
}
Run Code Online (Sandbox Code Playgroud)

游乐场

trait A {}
trait B: A {}

struct C;
impl A for C {}
impl B for C {}

fn foo(v: Box<A>) {}

fn main() {
    let c = C; …
Run Code Online (Sandbox Code Playgroud)

covariance rust

3
推荐指数
1
解决办法
185
查看次数

为什么 Rust 生命周期会破坏循环中的可变引用?

在尝试重构运行良好的 Rust 应用程序时,我尝试将循环的内容分离到一个新函数中。然而,在这个新重构的函数中,我需要传递一个必须可变的参数,并通过引用传递。突然之间,绝对内联工作的代码仅仅因为可变的引用传递而崩溃了。

我的问题是:有人可以解释一下为什么这样的“简单”更改不起作用吗?(即重构出原本未更改的代码的新函数)

我有一个关于该问题的最小演示,以及下面的一些工作比较。这是该代码的错误:

error[E0499]: cannot borrow `str_to_int` as mutable more than once at a time
  --> src/main.rs:30:22
   |
30 |         get_key(key, &mut str_to_int);
   |                      ^^^^^^^^^^^^^^^ `str_to_int` was mutably borrowed here in the previous iteration of the loop
Run Code Online (Sandbox Code Playgroud)

示例代码:

use std::collections::BTreeMap;

fn get_int (
    key: u32,
    values: &mut BTreeMap<u32, u32>,
) -> &u32 {
    values.entry(key).or_insert_with(|| { 1 })
}

fn get_key<'a> (
    key: &'a str,
    values: &'a mut BTreeMap<&'a str, u32>,
) -> &'a u32 {
    values.entry(key).or_insert_with(|| { 1 …
Run Code Online (Sandbox Code Playgroud)

refactoring mutable rust borrow-checker

3
推荐指数
1
解决办法
298
查看次数