Как использовать Pin вместо Arc для прохождения Vecпо ссылке на асинхронный блок - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть Vec<u8>, с которым я хочу выполнить какую-то операцию несколько раз. Я бы использовал Arc. Вот MVCE:

use futures::executor::{block_on, ThreadPool};
use futures::task::SpawnExt;
use std::pin::*;
use std::sync::Arc;
fn foo(b: Arc<Vec<u8>>) {
    println!("{:?}", b);
}

#[test]
fn pin_test() {
    let v = Arc::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    let mut pool = ThreadPool::new().unwrap();
    for _ in 0..10 {
        let v1 = v.clone();
        let handle = pool
            .spawn_with_handle(async {
                foo(v1);
            })
            .unwrap();
        block_on(handle);
    }
}

Я ожидал, что смогу Pin Vec<u8> вместо

use futures::executor::{block_on, ThreadPool};
use futures::task::SpawnExt;
use std::pin::*;
use std::sync::Arc;

fn foo(b: &[u8]) {
    println!("{:?}", b);
}
#[test]
fn pin_test() {
    let v = Pin::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    let mut pool = ThreadPool::new().unwrap();
    for _ in 0..10 {
        let v1 = v.clone();
        let handle = pool
            .spawn_with_handle(async {
                foo(&*v1);
            })
            .unwrap();
        block_on(handle);
    }
}

, что, естественно, дает ошибку 'argument requires that v1 is borrowed for 'static

Я понял, что Pin должен закрепить данные vec в определенной точке, чтобы все вызовы могли ссылаться на одни и те же данные. Как правильно использовать Пин, чтобы я мог передать ссылку на foo()

Пакеты: Фьючерсы 0.3 Руст 1.39 стабильный

1 Ответ

0 голосов
/ 07 ноября 2019

Отсутствует move.

Изменить

let handle = pool
        .spawn_with_handle(**async** {
            foo(&*v1);
        })
        .unwrap();

на

 let handle = pool
        .spawn_with_handle(**async move** {
            foo(&*v1);
        })
        .unwrap();
...