37
Rust’s “Ownership” & Move Semantics on Rust v.0.12-pre, 2014. Sep. 24. presentation in Rust Samurai 4

Rust's ownership and move semantics

Embed Size (px)

DESCRIPTION

Rust Samurai 4の資料

Citation preview

Page 1: Rust's ownership and move semantics

Rust’s “Ownership” & Move Semantics

on Rust v.0.12-pre, 2014. Sep. 24.presentation in Rust Samurai 4

Page 2: Rust's ownership and move semantics

Rust has rules:

• lifetime • ownership • borrowing

Page 3: Rust's ownership and move semantics

Lifetime“Lifetime” concept is a time span which a resource

(variable) life is valid in.

Page 4: Rust's ownership and move semantics

Lifetime (we have seen this graph in Rust guide, tutorial, or somewhere…)

{ let a = 1; { let b = 1; … … … }}

Page 5: Rust's ownership and move semantics

Lifetime

• You can think “Lifetime” is like a scope.

• On the end of the lifetime, the resource will be destructed (freed).

Page 6: Rust's ownership and move semantics

OwnershipWe can attempt that:

all allocated memory is “owned” by a unique someone.

Page 7: Rust's ownership and move semantics

Ownership

x vowning

let x = v;

Page 8: Rust's ownership and move semantics

Ownership

• The “owner” can change the owning value according to mutability.

• Ownership can transfer to an other variable.

• This is just move semantics in Rust.

• Ownership model guarantees the safeness in parallel.

Page 9: Rust's ownership and move semantics

BorrowingWe can “borrow” the resource which is owned by the other.

Page 10: Rust's ownership and move semantics

Borrowing

x vowning

y

Borrowing is similar to “reference”.

Page 11: Rust's ownership and move semantics

Borrowing

• “Borrowing” is similar to “reference”of other language.

• “Borrowing” is just only “borrowing” the resource which is owned by the other.

• “Borrowing” is under some restrictions in ownership concept.

Page 12: Rust's ownership and move semantics

Some restrictions about Ownership/Borrowing

Page 13: Rust's ownership and move semantics

Fundamental principals

• The borrowed value must not change without explicitly.

• If it changes arbitrarily, it is unclear and violates a safety of program.

Page 14: Rust's ownership and move semantics

Why we need a restriction?

• For safety.

• The arbitrary (non-explicit) change causes some serious safety issues.

• e.g. If the pointer is changed to the other location or `null` without explicitly while it is borrowed (referenced) from other?

Page 15: Rust's ownership and move semantics

Borrowing restrictions• Borrowing cannot change the borrowed one

without mutable permission by owner.

• Likewise, the original owner cannot change the owning value if it’s borrowed from others.

• We cannot borrow the same value as mutable more than once time.

Page 16: Rust's ownership and move semantics

let mut x: int = 1;

{

let y = &x;

*y = 10;// error: cannot assign

}

x = 2;// this is valid

Cannot assign to immutable dereference

Page 17: Rust's ownership and move semantics

let mut x: int = 1;

{

let y = &x;

*y = 10;// error: cannot assign

}

x = 2;// this is valid

Cannot assign to immutable dereference

if you wanna change `y`, `y` must be `&mut int`

Page 18: Rust's ownership and move semantics

let mut x: int = 1;

{

let y = &x;

let z = &mut x; // error!

}

Cannot mutable borrow, if the target has already been borrowed

(and vise versa)

Page 19: Rust's ownership and move semantics

let mut x: int = 1;

{

let y = &x;

let z = &mut x; // error!

}

Cannot mutable borrow, if the target has already been borrowed

(and vise versa)

This cannot ensure that the borrowed value by `y` is expected one.

Page 20: Rust's ownership and move semantics

let mut x: int = 1;

{

let y = &mut x;

let z = &mut x; // error!

}

Cannot mutable borrow, more than once time

Page 21: Rust's ownership and move semantics

let mut x: int = 1;

{

let y = &mut x;

let z = &mut x; // error!

}

Cannot mutable borrow, more than once time

This cannot ensure that the borrowed value by `y` is expected one.

Page 22: Rust's ownership and move semantics

let mut x: int = 1;

let y = &x; // after this, cannot change `x`

x = 10; // compile error!

Cannot change the value during it’s borrowed

Page 23: Rust's ownership and move semantics

let mut x: int = 1;

let y = &x; // after this, cannot change `x`

x = 10; // compile error!

Cannot change the value during it’s borrowed(sometimes called “freeze”)

This cannot ensure that the borrowed value by `y` is expected one.

Page 24: Rust's ownership and move semantics

Move semanticsIn Rust,

“move semantics” is transferring an ownership.

Page 25: Rust's ownership and move semantics

Move semantics• Transfer the ownership to the other.

• If we can move the ownership, as the result, we can assign the value with zero-copy like C++.

• Because Ownership concept ensures:

• Type system invalidates the old value.

• Then, there is no some owners, just only 1 owner!

Page 26: Rust's ownership and move semantics

How transfer the ownership?

Page 27: Rust's ownership and move semantics

• The typical case is copying Owned Box (std::owned::Box<T>).

• This copy is a shallow copy (Owned box is just like pointer), but Rust compiler consider to move ownership of the boxed value.

{

let x: Box<int> = box 1;

let y = x; // `x` is moved here! (`x` will dead)

println!(“{}”, x); // compile error. `x` has been moved

}

Page 28: Rust's ownership and move semantics

• What will it happen if we don’t move ownership hold by Owned Box?

• Then, there will be some inconsistency.

• If we do shallow-copy the value of Owned Box, there will be some objects that has the ownership of same location. This is against the rule.

• If we do deep-copy the value of it, we don’t have to use Owned box!

Page 29: Rust's ownership and move semantics

What type is a target of move?

• Almost, non-Copy kind, or ‘static kind.

• Move semantics is closely related to Rust’s type system.

• the value returning by function, or block.

• Send the value to other tasks (We can send only Send kinds).

Page 30: Rust's ownership and move semantics

Type kinds• Send

• All Send are ‘static kind.

• All types contains owning types, they must be Send.

• Copy

• Plain Old Data.

• ‘static

• Drop

• Send only can implement Drop.

• Default

Page 31: Rust's ownership and move semantics

Move: type need to move.

• `Send` kind

• Contains owning pointers.

• `Drop` kind (Implements `Drop` trait).

• procedure's environment

• non first-class types (but no details in rust doc…)

Page 32: Rust's ownership and move semantics

Move: the return value.

• The value returned by `return`, it’s would be moved from function/block. (This behavior is explained as “set to output slot”.)

Page 33: Rust's ownership and move semantics

Move: parameter type is opaque

• when `fn bar<T>(a: T) {…}`, we cannot specify the expected behavior.

• In this case, this parameter type can be only move. We must move it because we must ensure that it moves all ownerships of contained fields.

• If we specified the trait bound like `T: Copy`, this parameter will be copy.

Page 34: Rust's ownership and move semantics

Move: transfer a data from the task to other tasks

• In this case, the sent data must be `Send` kinds.

Page 35: Rust's ownership and move semantics

Move: procedure’s env.

• procedures may only be invoked once.

• After call them once, they are moved out.

Page 36: Rust's ownership and move semantics

Conclusion

Page 37: Rust's ownership and move semantics

Conclusion

• Rust has “ownership” concept to ensure the memory safety.

• “Ownership” consists of lifetime.

• Some types transfer their ownership if they’re re-assigned to other variables by following move semantics.