Rust-ownership

提供:Dev Guides
移動先:案内検索

錆-所有権

プログラムのメモリは、次のように割り当てることができます-

  • スタック
  • Heap

スタック

スタックは、後入れ先出し順に従います。 スタックには、コンパイル時にサイズがわかっているデータ値が格納されます。 たとえば、固定サイズi32の変数は、スタック割り当ての候補です。 そのサイズはコンパイル時に既知です。 サイズが固定されているため、すべてのスカラー型をスタックに格納できます。

実行時に値が割り当てられる文字列の例を考えてみましょう。 このような文字列の正確なサイズは、コンパイル時に決定できません。 したがって、スタック割り当ての候補ではなく、ヒープ割り当ての候補です。

Heap

ヒープメモリには、コンパイル時にサイズが不明なデータ値が格納されます。 動的データの保存に使用されます。 簡単に言えば、プログラムのライフサイクルを通じて変化する可能性があるデータ値にヒープメモリが割り当てられます。 ヒープはメモリ内の領域で、スタックと比較すると整理されていません。

所有権とは何ですか?

Rustの各値には、値の*所有者*と呼ばれる変数があります。 Rustに保存されているすべてのデータには、所有者が関連付けられています。 たとえば、構文-_let age = 30では、age_は値_30_の所有者です。

  • 各データは、一度に1人の所有者のみを持つことができます。
  • 2つの変数が同じメモリ位置を指すことはできません。 変数は常に異なるメモリ位置を指します。

所有権の譲渡

価値の所有権は次の方法で譲渡できます-

  • ある変数の値を別の変数に割り当てる。
  • 関数に値を渡します。
  • 関数から値を返します。

ある変数の値を別の変数に割り当てる

言語としてのRustの主なセールスポイントは、メモリの安全性です。 メモリの安全性は、誰が何をいつ使用できるかを厳密に制御することで実現されます。

次のスニペットを考慮してください-

fn main(){
   let v = vec![1,2,3];
  //vector v owns the object in heap

  //only a single variable owns the heap memory at any given time
   let v2 = v;
  //here two variables owns heap value,
  //two pointers to the same content is not allowed in rust

  //Rust is very smart in terms of memory access ,so it detects a race condition
  //as two variables point to same heap

   println!("{:?}",v);
}

上記の例では、ベクトルvを宣言しています。 所有権の考え方は、1つの変数のみがリソースにバインドされるということです。 v はリソースにバインドするか、 v2 はリソースにバインドします。 上記の例では、エラーがスローされます-移動した値の使用: `v`。 これは、リソースの所有権がv2に転送されるためです。 これは、所有権がvからv2(v2 = v)に移動され、移動後にvが無効になることを意味します。

関数に値を渡す

ヒープ内のオブジェクトをクロージャーまたは関数に渡すと、値の所有権も変わります。

fn main(){
   let v = vec![1,2,3];    //vector v owns the object in heap
   let v2 = v;             //moves ownership to v2
   display(v2);            //v2 is moved to display and v2 is invalidated
   println!("In main {:?}",v2);   //v2 is No longer usable here
}
fn display(v:Vec<i32>){
   println!("inside display {:?}",v);
}

関数から値を返す

関数の実行が完了すると、関数に渡された所有権は無効になります。 この問題を回避するには、関数が所有オブジェクトを呼び出し元に返すようにします。

fn main(){
   let v = vec![1,2,3];      //vector v owns the object in heap
   let v2 = v;               //moves ownership to v2
   let v2_return = display(v2);
   println!("In main {:?}",v2_return);
}
fn display(v:Vec<i32>)->Vec<i32> {
  //returning same vector
   println!("inside display {:?}",v);
}

所有権とプリミティブ型

プリミティブ型の場合、ある変数の内容が別の変数にコピーされます。 したがって、所有権の移動は発生しません。 これは、プリミティブ変数がオブジェクトよりも少ないリソースで済むためです。 次の例を考慮してください-

fn main(){
   let u1 = 10;
   let u2 = u1; //u1 value copied(not moved) to u2

   println!("u1 = {}",u1);
}

出力は– 10です。