بناء جملة الصدأ:سبب & موت فو بدلا من & فو في الصدأ عندما أعلن فو موت
سؤال
لروتين ج مثل
MPI_Comm_rank(MPI_Comm comm, int *rank);
يمكن الإعلان عن واجهة وظيفة الصدأ الخارجية مثل هذا:
extern crate libc;
use libc::{c_int};
#[link(name = "mpi")]
extern {
fn MPI_Comm_rank(mpi_comm: c_int,
rank: *mut c_int);
}
أدعو الربط مثل هذا ، الذي يعمل ، لكنه ترك لي في حيرة حول بناء الجملة:
pub static MPI_COMM_WORLD : libc::c_int = 0x44000000;
fn main() {
let mut rank: c_int = 999999;
/* but why '&mut rank' and not simply '&rank' ? */
unsafe {MPI_Comm_rank(MPI_COMM_WORLD, &mut rank)}
}
حاولت في الأصل
unsafe {MPI_Comm_rank(MPI_COMM_WORLD, &rank)}
ولكن هذا يعطي خطأ مترجم:
mismatched types: expected `*mut i32` but found `&i32` (values differ in mutability)
أعلنت 'رتبة' كما موت, وذلك ما يعطي?
المحلول
كنت الخلط بين اثنين من السمات المميزة تماما.
let mut x;
يجعل ملزمة قابلة للتغيير x
, ، مما يسمح لك بتعديل ما يرتبط به س (x = 42
) وبالنسبة للأنواع غير المرجعية لتعديل محتوياتها (x.y = 42
).لا يتحكم في قابلية تغيير الهدف من المراجع.
هذا يختلف عن نوع المراجع التي تتعامل معها.
&mut T
هو مرجع قابل للتغيير ويمكن إجباره على*mut T
.&T
هو مرجع غير قابل للتغيير يمكن إجباره على*const T
.
كما وظيفة كنت تدعو يريد *mut T
, ، يجب أن تمر عليه *mut T
أو أ &mut T
; *const T
أو &T
لن تفعل.
للتأكد ، يمكنك فقط أن تأخذ إشارة قابلة للتغيير إلى البيانات القابلة للتغيير ، لذلك let x = 42; &mut x
لا يعمل كما يحتاج let mut x
بدلا من let x
, ، ولكن هذا لا يزال متميزا تماما وهو جزء من قواعد الصدأ حول قابلية التغيير.
نصائح أخرى
تتوقع وظيفتك *mut c_int
مؤشر (مؤشر الخام قابلة للتغيير) ، وتحتاج إلى استخدام &mut
المشغل للحصول عليه.ومع ذلك ، يمكنك أن تأخذ فقط &mut
المؤشر إلى mut
المتغيرات ، وبالتالي تحتاج إلى إعلان rank
متغير مثل mut rank
.
إذا كانت وظيفتك متوقعة *const c_int
مؤشر ، هل سيكون قادرا على استخدام &
, ، ولكن هذا ليس هو الحال.