Upload
tetsuharu-ohzeki
View
1.785
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Rust Samurai 4の資料
Citation preview
Rust’s “Ownership” & Move Semantics
on Rust v.0.12-pre, 2014. Sep. 24.presentation in Rust Samurai 4
Rust has rules:
• lifetime • ownership • borrowing
Lifetime“Lifetime” concept is a time span which a resource
(variable) life is valid in.
Lifetime (we have seen this graph in Rust guide, tutorial, or somewhere…)
{ let a = 1; { let b = 1; … … … }}
Lifetime
• You can think “Lifetime” is like a scope.
• On the end of the lifetime, the resource will be destructed (freed).
OwnershipWe can attempt that:
all allocated memory is “owned” by a unique someone.
Ownership
x vowning
let x = v;
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.
BorrowingWe can “borrow” the resource which is owned by the other.
Borrowing
x vowning
y
Borrowing is similar to “reference”.
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.
Some restrictions about Ownership/Borrowing
Fundamental principals
• The borrowed value must not change without explicitly.
• If it changes arbitrarily, it is unclear and violates a safety of program.
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?
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.
let mut x: int = 1;
{
let y = &x;
*y = 10;// error: cannot assign
}
x = 2;// this is valid
Cannot assign to immutable dereference
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`
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)
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.
let mut x: int = 1;
{
let y = &mut x;
let z = &mut x; // error!
}
Cannot mutable borrow, more than once time
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.
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
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.
Move semanticsIn Rust,
“move semantics” is transferring an ownership.
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!
How transfer the ownership?
• 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
}
• 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!
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).
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
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…)
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”.)
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.
Move: transfer a data from the task to other tasks
• In this case, the sent data must be `Send` kinds.
Move: procedure’s env.
• procedures may only be invoked once.
• After call them once, they are moved out.
Conclusion
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.