El libro de Rust dice que los punteros en bruto "se consideran enviables (si su contenido se considera enviable)".
Sin embargo, por lo que puedo ver, el compilador genera el error the trait
core :: marker :: Send is not implemented for the type
cuando encuentra un puntero sin procesar a un tipo Sendable.
Podría ser que esté haciendo algo mal, podría ser que la documentación no esté clara o podría ser que el mensaje de error no sea útil para indicar cuál es el problema real con este código.
extern crate core;
use std::thread::Thread;
struct ShouldBeSendable {
x: i32
}
unsafe impl core::marker::Send for ShouldBeSendable { }
fn main() {
let sendablePtr : *const ShouldBeSendable = &ShouldBeSendable {x: 5};
let closure = move |:| {
*sendablePtr;
};
let something = Thread::spawn(closure);
}
Produce un error:
test.rs:15:21: 15:34 error: the trait `core::marker::Send` is not implemented for the type `*const ShouldBeSendable` [E0277]
test.rs:15 let something = Thread::spawn(closure);
^~~~~~~~~~~~~
test.rs:15:21: 15:34 note: `*const ShouldBeSendable` cannot be sent between threads safely
test.rs:15 let something = Thread::spawn(closure);
^~~~~~~~~~~~~
error: aborting due to previous error
$ rustc --version
rustc 1.0.0-dev (d15192317 2015-01-25 16:09:48 +0000)
Esto cambió recientemente, dejando los documentos desactualizados. ¡Gracias por notarlo y presentar un error!
@drewcrawford Puede usar la envoltura Unique
para hacer que su puntero sin formato Send
pueda. Esta versión modificada de su código funciona:
use std::ptr::Unique;
use std::thread::Thread;
#[derive(Copy)]
struct ShouldBeSendable {
x: i32
}
unsafe impl std::marker::Send for ShouldBeSendable { }
fn main() {
let ptr : *mut ShouldBeSendable = &mut ShouldBeSendable {x: 5}; // this is not `Send`
let sendablePtr = Unique(ptr); // but this is!
let closure = move |:| {
// `sendablePtr` con be moved inside this closure
let ptr = sendablePtr.0; // unpack the raw pointer
println!("{}", unsafe { (*ptr).x })
};
let something = Thread::scoped(closure).join();
}
@japaric ejemplo para Rust 1.25 usando NonNull
.
https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable
Comentario más útil
@japaric ejemplo para Rust 1.25 usando
NonNull
.https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable