简体   繁体   English

编译器如何推断 Box 正在借用它的内容借用的那个?

[英]How does compiler infer that Box is borrowing the one which its content borrows?

let s: String = String::from("some message");

let b: Box<&String> = Box::<&String>::new(&s);

drop(s);

let another_box = b; // error! b (which borrows s) is used later!

So, above code looks very simple.所以,上面的代码看起来很简单。

b is clearly borrowing s , in the human sense. b在人类意义上显然是借用了s

But, I think this is quite magical: How can the compiler knows that without any lifetime statements?但是,我认为这很神奇:没有任何生命周期语句,编译器怎么能知道呢?

According to the Rust's standard library, Box 's declaration is as follows:根据 Rust 的标准库, Box的声明如下:

pub struct Box<T, A = Global>(_, _)
    where A: AllocRef, T: ?Sized;

And what I think what it really is is as follows:我认为它的真正含义如下:

pub struct Box<'a, T, A = Global>(_, _)
    where A: AllocRef, T: ?Sized + 'a;

I don't think that the lifetime(or the borrowing) moves automatically for all the situations where a struct has a generic paramter type.对于结构具有通用参数类型的所有情况,我认为生命周期(或借用)不会自动移动。 Or is it??还是它??

The lifetime is part of the type T that's wrapped in the box in this case.在这种情况下,生命周期是包装在盒子中的类型T的一部分。

You wrap &s of type &'a String in the box, where 'a is an appropriate lifetime of the reference, inferred by the compiler.您将 & &'a String类型的&s包装在框中,其中'a是引用的适当生命周期,由编译器推断。 The type of b is therefore Box<&'a String> , so it includes the same lifetime parameter.因此b的类型是Box<&'a String> ,因此它包含相同的生命周期参数。 The box itself doesn't need an explicit lifetime parameter – it's generic over an arbitrary type, and there is no reason that type needs to have static lifetime.盒子本身不需要显式的生命周期参数——它对任意类型都是通用的,并且没有理由该类型需要具有 static 生命周期。

This is not specific to a Box .这不是特定于Box的。 For example it works the same way for PhantomData , although PhantomData doesn't even use its type parameter in any way:例如,它对PhantomData的工作方式相同,尽管PhantomData甚至不以任何方式使用其类型参数:

use std::marker::PhantomData;

fn make_phantom<T>(_: T) -> PhantomData<T> {
    PhantomData
}

fn main() {
    let s: String = String::from("some message");
    let phantom = make_phantom(&s);
    drop(s);
    let _another_phantom = phantom;
}

results in the same error, ie from the viewpoint of the borrow checker, phantom borrows s , though in reality it doesn't hold a reference to s .导致相同的错误,即从借用检查器的角度来看, phantom借用s ,尽管实际上它不包含对s的引用。

( Playground ) 游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM