يقول كتاب Rust أن المؤشرات الأولية "تعتبر قابلة للإرسال (إذا كانت محتوياتها قابلة للإرسال)".
ولكن مما يمكنني رؤيته ، يقوم المترجم بإنشاء الخطأ the trait
core :: marker :: Send is not implemented for the type
عندما يواجه مؤشرًا خامًا لنوع قابل للإرسال.
قد يكون الأمر أنني أفعل شيئًا خاطئًا ، أو قد يكون التوثيق غير واضح أو قد تكون رسالة الخطأ غير مفيدة في الإشارة إلى المشكلة الحقيقية في هذا الرمز مهما كانت.
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);
}
ينتج خطأ:
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)
تغير هذا مؤخرًا ، وترك المستندات قديمة. شكرا لملاحظة وتقديم خطأ!
drewcrawford يمكنك استخدام Unique
لجعل المؤشر الخام Send
قادرًا. تعمل هذه النسخة المعدلة من التعليمات البرمجية الخاصة بك:
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 لـ Rust 1.25 باستخدام NonNull
.
https://play.rust-lang.org/؟gist=1ce2532a0eefc60695663c26faddebe1&version=stable
التعليق الأكثر فائدة
مثال japaric لـ Rust 1.25 باستخدام
NonNull
.https://play.rust-lang.org/؟gist=1ce2532a0eefc60695663c26faddebe1&version=stable