Rust 没有“解开”的“pin_项目”听起来怎么样`

Rust 没有“解开”的“pin_项目”听起来怎么样`,rust,reference,rust-pin,Rust,Reference,Rust Pin,pin_project允许结构设计器从对整个结构的固定引用中获取对结构字段的固定引用。它还允许设计器指定哪些字段需要固定引用,哪些字段只需获得常规引用: #[pin_项目] 结构演示{ #[pin码] 场a:a, 场_b:b, } impl演示{ fn显示参考(自:引脚){ 让它=self.project(); 让field_a:Pin=this.field_a; 让field_b:&mut b=this.field_b; } } 我的问题是,如果没有b:Unpin,那么字段b部分如何保持完好

pin_project
允许结构设计器从对整个结构的固定引用中获取对结构字段的固定引用。它还允许设计器指定哪些字段需要固定引用,哪些字段只需获得常规引用:

#[pin_项目]
结构演示{
#[pin码]
场a:a,
场_b:b,
}
impl演示{
fn显示参考(自:引脚){
让它=self.project();
让field_a:Pin=this.field_a;
让field_b:&mut b=this.field_b;
}
}
我的问题是,如果没有
b:Unpin
,那么
字段b
部分如何保持完好?固定引用的创建会“固定”结构,强制被引用的结构不能移出其在内存中的位置。这个属性不会像易变性一样递归地应用吗?如果
Demo
被固定,这是否意味着
字段a
字段b
被隐式固定?

如中所述,
Pin
所做的保证不一定是递归的

这里的主要保证是“
Pin
防止某些值(由封装在
Pin
中的指针指向)被移动。”根据设计,这特别适用于这些值作为一个整体,而
Pin
本身不声明这些值的字段

Pin
可以进行不同的设计,但这种特殊的方法非常有用,因为它让每个特定的用例自己决定是否需要“结构性”pinning(字段必须自己固定)和“非结构性”pinning(可以安全地移动或交换字段)

例如,想象一个必须固定的
PinMe
类型的值,并将该值放入结构
包装器中。指向此类
包装器
值的指针必须是
Pin
指针,以防止移动内部
PinMe

#[pin_项目]
结构包装器{
#[pin码]
佩妮:品妮,
}
fn f(w:销){
//我们无法移动'w'指向的'Wrapper',因为那样会移动'w.pinted'。
//我们所能做的就是抓住一个指向“PinMe”的固定指针:
让内部:Pin=w.project().pinted;
}
但是如果
Wrapper
有另一个与
PinMe
完全无关的字段,则没有理由不移动或交换该字段:

#[pin_项目]
结构包装器{
#[pin码]
佩妮:品妮,
柜台:i32,
}
fn f(w:销){
设w=w.project();
让内部:销=w销;
let counter:&mut i32=w.counter;
//这些类型的操作不会影响“PinMe”:
*计数器+=3;
mem::更换(计数器,5);
}
结构固定与非结构固定的选择完全取决于需要维护的不变量。如果
field_b
需要保持在
field_a
的旁边,则向其添加
#[pin]
。但如果这不是您的
演示类型所需的内容,您可以省略它,这样可以提供较少的保证,但仍然是安全的

编辑:此外,即使该额外字段未实现
Unpin
,只要没有任何内容构建直接指向它的
Pin
,这也适用。例如:

#[pin_项目]
结构包装器{
#[pin码]
佩妮:品妮,
//我们对这种类型一无所知,只知道它的大小。
//因此,我们不能假设它实现了“Unpin”。
柜台:T,,
}
fn f(带销,其他:T){
设w=w.project();
让内部:销=w销;
让计数器:&mut T T=w计数器;
//这还可以:
mem::更换(计数器、其他);
}
如中所述,
Pin
做出的保证不一定是递归的

这里的主要保证是“
Pin
防止某些值(由封装在
Pin
中的指针指向)被移动。”根据设计,这特别适用于这些值作为一个整体,而
Pin
本身不声明这些值的字段

Pin
可以进行不同的设计,但这种特殊的方法非常有用,因为它让每个特定的用例自己决定是否需要“结构性”pinning(字段必须自己固定)和“非结构性”pinning(可以安全地移动或交换字段)

例如,想象一个必须固定的
PinMe
类型的值,并将该值放入结构
包装器中。指向此类
包装器
值的指针必须是
Pin
指针,以防止移动内部
PinMe

#[pin_项目]
结构包装器{
#[pin码]
佩妮:品妮,
}
fn f(w:销){
//我们无法移动'w'指向的'Wrapper',因为那样会移动'w.pinted'。
//我们所能做的就是抓住一个指向“PinMe”的固定指针:
让内部:Pin=w.project().pinted;
}
但是如果
Wrapper
有另一个与
PinMe
完全无关的字段,则没有理由不移动或交换该字段:

#[pin_项目]
结构包装器{
#[pin码]
佩妮:品妮,
柜台:i32,
}
fn f(w:销){
设w=w.project();
让内部:销=w销;
let counter:&mut i32=w.counter;
//这些类型的操作不会影响“PinMe”:
*计数器+=3;
mem::更换(计数器,5);
}
结构固定与非结构固定的选择完全取决于需要维护的不变量。如果
field_b
需要保持在
field_a
的旁边,则向其添加
#[pin]
。但如果这不是您的
演示类型所需的内容,您可以省略它,这样可以提供较少的保证,但仍然是安全的

编辑:此外,即使该额外字段未实现
Unpin
,只要没有任何内容构成
Pin
点I,此项也适用