錆びた構文:foo が mut を宣言したときに Rust で &foo の代わりに &mut foo が使用される理由

StackOverflow https://stackoverflow.com//questions/25091631

  •  02-01-2020
  •  | 
  •  

質問

次のような C ルーチンの場合

MPI_Comm_rank(MPI_Comm comm, int *rank);

Rust の外部関数インターフェイスは次のように宣言できます。

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)

「ランク」を mut として宣言しましたが、何が得られるでしょうか?

役に立ちましたか?

解決

2 つの完全に異なる機能を混同しています。

let mut x; 変更可能なバインディングを作成します 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, しかし、それは依然として完全に異なり、可変性に関する Rust のルールの一部です。

他のヒント

あなたの関数は*mut c_intポインタ(可変の生ポインタ)を想定しており、&mut演算子を使用して入手する必要があります。ただし、&mut変数へのmutポインタを実行することができます。したがって、rank変数をmut rankとして宣言する必要があります。

関数が*const c_intポインタを予期している場合は、&を使用することができますが、これはそうではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top