Slide 1

Slide 1 text

イテレーションとRust で見る Swift の所有権 @hokuron Fenrir inc.

Slide 2

Slide 2 text

自己紹介 清水拓磨 @hokuron ドメイン駆動設計 iOS Ruby on Rails Rust ← new フェンリル株式会社

Slide 3

Slide 3 text

イテレーションとRust の挙動から 来たるSwift の所有権に触れてみる

Slide 4

Slide 4 text

Ownership Manifesto 所有権に関する提案や考察 実装の優先順位 ABI Dashboard > Ownership 排他則 ( 排他アクセス) co-routine 一部だけ; read / modify アクセッサ向け? __shared / __owned 引数 apple/swift のmaster ブランチにて確認

Slide 5

Slide 5 text

Ownership Manifesto > Explicit tools for ownership > for loops ( 未実装) 今後、仕様が変わることもあります。

Slide 6

Slide 6 text

イテレーションにおける 所有権 不変イテレーション 可変イテレーション 消費イテレーション generator (co-routine) ↑ 今回は話しません

Slide 7

Slide 7 text

不変イテレーション for shared employee in company.employees { if !employee.respected { throw CatastrophicHRFailure() } } イテレーションの中で要素を変更しない イテレーション変数は要素への 共有(shared) 参照 要素の取り出しにコピーが発生しない Collection に対するnonmutating な操作 Collection protocol に準拠していれば shared の明示的な宣言は不要

Slide 8

Slide 8 text

不変イテレーション Array など内部的にストレージ(= バッファ) を持つ型の 場合 そのストレージに対する排他アクセスが発生 イテレーション中はこのArray を変更できない

Slide 9

Slide 9 text

可変イテレーション for inout employee in company.employees { employee.respected = true } イテレーションの中で要素を変更可能 イテレーション変数は要素への 可変(inout) 参照 要素の取り出しにコピーが発生しない MutableCollection に対するmutating な操作

Slide 10

Slide 10 text

可変イテレーション Array など内部的にストレージ(= バッファ) を持つ型の 場合 そのストレージに対する排他アクセスが発生 イテレーション中はこのArray にアクセスそのもの ができない NSArray などの参照型のコレクションには適用され ない すべての操作がnonmutating になるため

Slide 11

Slide 11 text

Rust における共有参照・可変参照 共有参照 let mut prime_nums = vec![2, 3, 5, 7]; let prime_ref: &vec = &prime_nums; // cannot borrow `prime_nums` as mutable // because it is also borrowed as immutable prime_nums.remove(0); dbg!(prime_ref); dbg!(prime_nums); 共有参照としての借用が終わるまで 可変操作( 借用) ができない 参照中に元の値が変更されないことを保証 安全

Slide 12

Slide 12 text

不変イテレーション Array など内部的にストレージ(= バッファ) を持つ型の 場合 イテレーション中はこのArray を変更できない

Slide 13

Slide 13 text

Rust における共有参照・可変参照 可変参照 let mut prime_nums = vec![2, 3, 5, 7]; let prime_ref = &mut prime_nums; // cannot borrow `prime_nums` as immutable // because it is also borrowed as mutable println!("{:?}", prime_nums); println!("{:?}", prime_ref); 可変参照としての借用が終わるまで 別の借用( 共有参照すら) ができない 変更中の値が使われないことを保証 安全

Slide 14

Slide 14 text

可変イテレーション Array など内部的にストレージ(= バッファ) を持つ型の 場合 イテレーション中はこのArray にアクセスそのもの ができない

Slide 15

Slide 15 text

消費イテレーション for owned employee in company.employees { newCompany.employees.append(employee) } いつものイテレーション ( owned の明示は不要) イテレーション変数は要素を owned( 所有) する Sequence protocol に対するconsuming ( 消費) 操作

Slide 16

Slide 16 text

消費イテレーション イテレーション変数は要素を owned( 所有) する non-copyable 型 ( 未実装) から要素の所有権を得る Sequence protocol 破壊的な消費をしながらのイテレーション 1 度目とそれ以降のイテレーションが同じ結果にな るとは限らない 2 度目以降のイテレーションは未定義動作

Slide 17

Slide 17 text

Rust における消費イテレーション let prime_nums = vec![2, 3, 5, 7]; for prime in prime_nums { println!("{:?}", prime); } // borrow of moved value: `prime_nums` println!("{:?}", prime_nums.is_empty()); 未定義動作どころか未初期化状態になり コンパイルが通らない prime_nums 変数そのものがmove( 移動) する

Slide 18

Slide 18 text

まとめ 不変イテレーション 変数をshared で宣言 → 最適化で宣言不要になる場合も nonmutating な操作が可能 ループ中にコレクションに対する可変操作はでき ない Rust は安全

Slide 19

Slide 19 text

まとめ 可変イテレーション 変数をinout で宣言 mutating な操作が可能 ループ中にコレクションにアクセスできない Rust は安全

Slide 20

Slide 20 text

まとめ 消費イテレーション 変数をowned で宣言 → 所有の意図を明示する以外は省略可能? non-copyable 型との組み合わせで花ひらく? Rust は安全

Slide 21

Slide 21 text

まとめ Rust は安全

Slide 22

Slide 22 text

ご静聴ありがとうございました!