rust如何放置篝火_【译文】Rust异步编程: Pinning

8c3dc6d4bc5122e6293f72b3c46e0898.png

原文:选自《Rust异步编程》第4章 Pinning

译者注:如果你一时半会没啃动Pinning,也别心急,试试阅读这篇《Rust的Pin与Unpin - Folyd》,理解起来会容易不少。

Pinning详解

让我们尝试使用一个比较简单的示例来了解pinning。前面我们遇到的问题,最终可以归结为如何在Rust中处理自引用类型的引用的问题。

现在,我们的示例如下所示:

use std::pin::Pin;
​
#[derive(Debug)]
struct Test {
    
    a: String,
    b: *const String,
}
​
impl Test {
    
    fn new(txt: &str) -> Self {
    
        Test {
    
            a: String::from(txt),
            b: std::ptr::null(),
        }
    }
​
    fn init(&mut self) {
    
        let self_ref: *const String = &self.a;
        self.b = self_ref;
    }
​
    fn a(&self) -> &str {
    
        &self.a
    }
​
    fn b(&self) -> &String {
    
        unsafe {
    &*(self.b)}
    }
}

Test提供了获取字段a和b值引用的方法。由于b是对a的引用,因此我们将其存储为指针,因为Rust的借用规则不允许我们定义这种生命周期。现在,我们有了所谓的自引用结构。

如果我们不移动任何数据,则该示例运行良好,可以通过运行示例观察:

fn main() {
    
    let mut test1 = Test::new("test1");
    test1.init();
    let mut test2 = Test::new("test2");
    test2.init();
​
    println!("a: {}, b: {}", test1.a(), test1.b());
    println!("a: {}, b: {}", test2.a(), test2.b());
​
}

我们得到了我们期望的结果:

a: test1, b: test1
a: test2, b: test2

让我们看看如果将test1test2交换导致数据移动会发生什么:

fn main() {
    
    let mut test1 = Test::new("test1");
    test1.init();
    let mut test2 = Test::new("test2");
    test2.init();
​
    println!("a: {}, b: {}", test1.a(), test1.b());
    std::mem::swap(&mut test1, &mut test2);
    println!(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值