Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rustってどんな言語
Search
unisuke
November 20, 2022
Technology
0
160
Rustってどんな言語
unisuke
November 20, 2022
Tweet
Share
More Decks by unisuke
See All by unisuke
Verified Software Toolchain C ~Coqを用いたCプログラムの検証~
uni_82
0
59
はじめてのIT勉強会 プリンシプルオブプログラミングPart.3
uni_82
0
150
2021.01はじめてのIT勉強会.pdf
uni_82
0
130
20201129WBALT.pdf
uni_82
0
69
2020.11.26ポートフォリオを素敵にしたい 副代表のゆるゆるLT第1段
uni_82
0
81
はじめてのIT勉強会 プリンシプルオブプログラミング
uni_82
0
220
2020.10.14 はじめての〇〇 超LT会- vol.1 #ultralt
uni_82
0
69
Goconference_20__1_.pdf
uni_82
0
91
はじめてのIT勉強会.pdf
uni_82
0
120
Other Decks in Technology
See All in Technology
AWS CDK 入門ガイド これだけは知っておきたいヒント集
anank
4
510
成長し続けるアプリのためのテストと設計の関係、そして意思決定の記録。
sansantech
PRO
0
140
「クラウドコスト絶対削減」を支える技術—FinOpsを超えた徹底的なクラウドコスト削減の実践論
delta_tech
4
180
アクセスピークを制するオートスケール再設計: 障害を乗り越えKEDAで実現したリソース管理の最適化
myamashii
1
270
対話型音声AIアプリケーションの信頼性向上の取り組み
ivry_presentationmaterials
1
630
Delta airlines Customer®️ USA Contact Numbers: Complete 2025 Support Guide
deltahelp
0
1.1k
第64回コンピュータビジョン勉強会「The PanAf-FGBG Dataset: Understanding the Impact of Backgrounds in Wildlife Behaviour Recognition」
x_ttyszk
0
140
NewSQLや分散データベースを支えるRaftの仕組み - 仕組みを理解して知る得意不得意
hacomono
PRO
3
220
VGGT: Visual Geometry Grounded Transformer
peisuke
1
570
Getting to Know Your Legacy (System) with AI-Driven Software Archeology (WeAreDevelopers World Congress 2025)
feststelltaste
1
180
Copilot coding agentにベットしたいCTOが開発組織で取り組んだこと / GitHub Copilot coding agent in Team
tnir
0
130
freeeのアクセシビリティの現在地 / freee's Current Position on Accessibility
ymrl
2
260
Featured
See All Featured
Practical Orchestrator
shlominoach
189
11k
RailsConf 2023
tenderlove
30
1.1k
Making Projects Easy
brettharned
116
6.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.3k
Git: the NoSQL Database
bkeepers
PRO
430
65k
Speed Design
sergeychernyshev
32
1k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
YesSQL, Process and Tooling at Scale
rocio
173
14k
Code Reviewing Like a Champion
maltzj
524
40k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
4 Signs Your Business is Dying
shpigford
184
22k
How to Ace a Technical Interview
jacobian
278
23k
Transcript
Rustってどんな言語
Rustが目指すのはいいとこ取り っっっっっk 低レベルの制御 メモリ安全性 C, C++.. Python, JavaScript… Rust
C++が安全でなくてRustが安全 っっっっっk っっs 1 std::vector<int> v { 10, 11 };
2 int *vptr = &v[1]; 3 v.push_back(12); 4 std::cout << *vptr; C++
C++が安全でなくてRustが安全 っっっっっk っっs 1 std::vector<int> v { 10, 11 };
2 int *vptr = &v[1]; 3 v.push_back(12); 4 std::cout << *vptr; C++ Bug (use-after-free) result
C++が安全でなくてRustが安全 っっっっっk 10 11 v 1 std::vector<int> v { 10,
11 }; 2 int *vptr = &v[1]; 3 v.push_back(12); 4 std::cout << *vptr; C++
C++が安全でなくてRustが安全 っっっっっk 10 11 v 1 std::vector<int> v { 10,
11 }; 2 int *vptr = &v[1]; 3 v.push_back(12); 4 std::cout << *vptr; C++ vptr
C++が安全でなくてRustが安全 っっっっっk 10 11 v 1 std::vector<int> v { 10,
11 }; 2 int *vptr = &v[1]; 3 v.push_back(12); 4 std::cout << *vptr; C++ vptr 10 11 v 12
C++が安全でなくてRustが安全 っっっっっk 10 11 v 1 std::vector<int> v { 10,
11 }; 2 int *vptr = &v[1]; 3 v.push_back(12); 4 std::cout << *vptr; C++ vptr すでに解放済みのメモリ をさしている →ダングリングポインタ
C++が安全でなくてRustが安全 っっっっっk っっs 1 let mut v = vec![10, 11];
2 let vptr = &mut v[1]; 3 v.push(12); 4 println!("{}", *vptr); Rust
C++が安全でなくてRustが安全 っっっっっk っっs 1 let mut v = vec![10, 11];
2 let vptr = &mut v[1]; 3 v.push(12); 4 println!("{}", *vptr); Rust コンパイルエラー result
所有権システム っっっっっk • メモリはコンパイラがコンパイル時にチェックする一定の規則とともに 所有権システムを通じて管理されている • Rustの各値は、所有者と呼ばれる変数と対応している。 • いかなる時も所有者は一つである。 •
所有者がスコープから外れたら、値は破棄される。 所有権の原則
所有権システム っっっっっk let s1 = String::from("hello"); let s2 = s1;
println!("s2 = {}", s2); //println!("s1 = {}", s1); Rust “hello” s1 所有者 • Rustの各値は、所有者と呼ばれる変数と対応している。 所有権の原則
所有権システム っっっっっk let s1 = String::from("hello"); let s2 = s1;
println!("s2 = {}", s2); //println!("s1 = {}", s1); Rust “hello” s1 • いかなる時も所有者は一つである。 所有権の原則 s2 所有者
所有権システム っっっっっk let s1 = String::from("hello"); let s2 = s1;
println!("s2 = {}", s2); //println!("s1 = {}", s1); Rust “hello” s1 s2 所有者 s2 = hello result
所有権システム っっっっっk let s1 = String::from("hello"); let s2 = s1;
println!("s2 = {}", s2); println!("s1 = {}", s1); Rust “hello” s1 s2 所有者 コンパイルエラー(s1: value borrowed here after move) result
所有権システムのメリット っっっっっk • メモリに起因する問題を克服し てメモリ安全性が保証される • 解放忘れ/二重解放のトラブル がなくなる • 脆弱性の原因になる挙動を避け
られる(ex. ダングリングポイ ンタ) vs 手動でメモリ管理 • ガベージコレクタの実行速度の 遅さ、メモリ効率というデメリ ットを克服する • 効率的で高速 vs ガベージコレクタ
所有権と関数 っっっっっk fn main() { let s1 = String::from("hello"); show_str(s1);
println!("s1 = {}", s1); } fn show_str(str: String) { println!("{}", str); } Rust “hello” s1 str 所有者
所有権と関数 っっっっっk fn show_message(str: String) { println!("{}", str); } Rust
“hello” s1 • 所有者がスコープから外れたら、値は破棄される。 所有権の原則 str 所有者 変数strがスコープ抜ける スコープ抜ける 破棄
所有権と関数 っっっっっk fn main() { let s1 = String::from("hello"); show_str(s1);
println!("s1 = {}", s1); } Rust “hello” s1 破棄 コンパイルエラー(s1: value borrowed here after move) result
関数に渡した値を呼び出し元で再度使いたいとき① っっっっっk fn main() { let mut s1 = String::from("hello");
s1 = show_str(s1); println!("s1 = {}", s1); } fn show_str(str: String) -> String { println!("{}", str); str } Rust “hello” s1 str 所有者
関数に渡した値を呼び出し元で再度使いたいとき① っっっっっk fn main() { let mut s1 = String::from("hello");
s1 = show_str(s1); println!("s1 = {}", s1); } fn show_str(str: String) -> String { println!("{}", str); str } Rust “hello” s1 str 所有者
関数に渡した値を呼び出し元で再度使いたいとき① っっっっっk fn main() { let mut s1 = String::from("hello");
s1 = show_str(s1); println!("s1 = {}", s1); } fn show_str(str: String) -> String { println!("{}", str); str } Rust s1 = hello result
共有参照 っっっっっk • 与えた値を参照する参照を生成することができる • 値を参照するだけで、所有はしない • 関数の引数に参照を取ることを借用と呼ぶ • データへの一時的なアクセスを許し、操作的にはポインタに相当する
• 複製が可能 • 共有参照が存在する場合、所有者も値の変更ができない &[変数名 / 値] ex. &s1, &String::from("hello") 記法
関数に渡した値を呼び出し元で再度使いたいとき② っっっっっk fn main() { let s1 = String::from("hello"); show_str(&s1);
println!("s1 = {}", s1); } fn show_str(str: &String) { println!("{}", str); } Rust “hello” s1 所有者
関数に渡した値を呼び出し元で再度使いたいとき② っっっっっk fn main() { let s1 = String::from("hello"); show_str(&s1);
println!("s1 = {}", s1); } fn show_str(str: &String) { println!("{}", str); } Rust “hello” s1 str 所有者 s1の値を参照 所有権の移動は 発生しない
関数に渡した値を呼び出し元で再度使いたいとき② っっっっっk fn show_str(str: &String) { println!("{}", str); } Rust
“hello” s1 str 所有者 s1の値を参照 所有権の移動は 発生しない 変数strがスコープ抜けるが、strは所有権を持た ないため、値は破棄されない
関数に渡した値を呼び出し元で再度使いたいとき② っっっっっk fn main() { let s1 = String::from("hello"); show_str(&s1);
println!("s1 = {}", s1); } fn show_str(str: &String) { println!("{}", str); } Rust s1 = hello result
値を変更したいときは所有権持たせるしかない。。? っっっっっk fn main() { let s1 = String::from("hello"); show_str(&s1);
println!("s1 = {}", s1); } fn show_str(str: &String) { str.push_str(" sample"); println!("{}", str); } Rust コンパイルエラー `str` is a `&` reference, so the data it refers to cannot be borrowed as mutable result
可変参照 っっっっっk • 可変な参照を生成する • 値を参照するだけで、所有はしない &mut [変数名 / 値]
ex. &mut s1 記法
関数内で値を変更 っっっっっk fn main() { let mut s1 = String::from("hello");
show_str(&mut s1); println!("s1 = {}", s1); } fn show_str(str: &mut String) { str.push_str(" sample"); println!("{}", str); } Rust hello sample s1 = hello sample result
可変参照 っっっっっk • 特定のスコープで、ある特定のデータに対しては、 一つしか可変な参 照を持てない • 不変な参照をしている間は、可変な参照をすることはできない 制約 1.
2つ以上のポインタが同じデータに同時にアクセスする 2. 少なくとも一つのポインタがデータに書き込みを行っている 3. データへのアクセスを同期する機構が使用されていない データ競合が起こる条件 データ競合 を防ぐこと ができる
ライフタイム っっっっっk • 全ての参照に有効時間が設定されている • 参照の完全な形は参照型の完全な形は &'a mut Tまたは &'a
Tで、'a は参照の有効期限、ライフタイムを省略できる規約もいくつかある
C++が安全でなくてRustが安全 っっっっっk っっs 1 let mut v = vec![10, 11];
2 let vptr = &mut v[1]; 3 v.push(12); 4 println!("{}", *vptr); Rust コンパイルエラー result
ダングリングポインタをコンパイルエラーで防ぐ っっっっっk っっs fn sample() { let mut data: Vec<i32>
= vec![10, 11]; // ↓ let vptr = &mut v[1]; let vptr : &'b i32 = Index::index::<'b>(&'b data, 0); // ↓ v.push(12); Vec::push(&'c mut data, 4) println!("{}", x); } Rust
ダングリングポインタをコンパイルエラーで防ぐ っっっっっk っっs fn sample() { 1 let mut data:
Vec<i32> = vec![10, 11]; 2 let x: &'b i32 = Index::index::<'b>(&'b data, 0); 3 Vec::push(&'c mut data, 4); 4 println!("{}", x); } Rust --------+'a | ----+'b | +'c | | ----+ | --------+
ダングリングポインタをコンパイルエラーで防ぐ っっっっっk っっs fn sample() { 1 let mut data:
Vec<i32> = vec![10, 11]; 2 let x: &'b i32 = Index::index::<'b>(&'b data, 0); 3 Vec::push(&'c mut data, 4); 4 println!("{}", x); } Rust --------+'a | ----+'b | +'c | | ----+ | --------+ xは'bで生存しなくてはいけない
ダングリングポインタをコンパイルエラーで防ぐ っっっっっk っっs fn sample() { 1 let mut data:
Vec<i32> = vec![10, 11]; 2 let x: &'b i32 = Index::index::<'b>(&'b data, 0); 3 Vec::push(&'c mut data, 4); 4 println!("{}", x); } Rust --------+'a | ----+’b | | | +‘c | | ----+ | --------+ xは'bで生存しなくてはいけない dataを参照する参照が’bで生存することを要求する
可変参照 っっっっっk • 特定のスコープで、ある特定のデータに対しては、 一つしか可変な参 照を持てない • 不変な参照をしている間は、可変な参照をすることはできない 制約 1.
2つ以上のポインタが同じデータに同時にアクセスする 2. 少なくとも一つのポインタがデータに書き込みを行っている 3. データへのアクセスを同期する機構が使用されていない データ競合が起こる条件 データ競合 を防ぐこと ができる
ダングリングポインタをコンパイルエラーで防ぐ っっっっっk っっs 不変な参照をしている間に可変な参照をすることはできないのでエラー fn sample() { 1 let mut
data: Vec<i32> = vec![10, 11]; 2 let x: &'b i32 = Index::index::<'b>(&'b data, 0); 3 Vec::push(&'c mut data, 4); 4 println!("{}", x); } Rust --------+'a | ----+’b | | | +‘c | | ----+ | --------+ xは'bで生存しなくてはいけない dataを参照する参照が’bで生存することを要求する 新しい可変参照を生成⚠
unsafe Rust っっっっっk • コンピュータのハードウェアが本質的にunsafeであるため、unsafeな処理 ができないと、特定の制御ができない • デバッグのため、unsafeブロックを小さくすることを推奨している • 生ポインタを参照外しすること
• unsafeな関数やメソッドを呼ぶこと • 可変で静的な変数にアクセスしたり変更すること • unsafeなトレイトを実装すること unsafe superpowers(safe Rustでは行えない4つの行動)