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
170
Rustってどんな言語
unisuke
November 20, 2022
Tweet
Share
More Decks by unisuke
See All by unisuke
Verified Software Toolchain C ~Coqを用いたCプログラムの検証~
uni_82
0
67
はじめてのIT勉強会 プリンシプルオブプログラミングPart.3
uni_82
0
150
2021.01はじめてのIT勉強会.pdf
uni_82
0
130
20201129WBALT.pdf
uni_82
0
70
2020.11.26ポートフォリオを素敵にしたい 副代表のゆるゆるLT第1段
uni_82
0
82
はじめてのIT勉強会 プリンシプルオブプログラミング
uni_82
0
230
2020.10.14 はじめての〇〇 超LT会- vol.1 #ultralt
uni_82
0
70
Goconference_20__1_.pdf
uni_82
0
92
はじめてのIT勉強会.pdf
uni_82
0
120
Other Decks in Technology
See All in Technology
Escaping_the_Kraken_-_October_2025.pdf
mdalmijn
0
150
AWS IoT 超入門 2025
hattori
0
270
生成AIで「お客様の声」を ストーリーに変える 新潮流「Generative ETL」
ishikawa_satoru
1
370
ACA でMAGI システムを社内で展開しようとした話
mappie_kochi
1
310
『バイトル』CTOが語る! AIネイティブ世代と切り拓くモノづくり組織
dip_tech
PRO
1
100
Trust as Infrastructure
bcantrill
1
370
能登半島地震で見えた災害対応の課題と組織変革の重要性
ditccsugii
0
220
AWS 잘하는 개발자 되기 - AWS 시작하기: 클라우드 개념부터 IAM까지
kimjaewook
0
120
Adminaで実現するISMS/SOC2運用の効率化 〜 アカウント管理編 〜
shonansurvivors
4
420
[Keynote] What do you need to know about DevEx in 2025
salaboy
0
140
後進育成のしくじり〜任せるスキルとリーダーシップの両立〜
matsu0228
7
3.2k
SwiftUIのGeometryReaderとScrollViewを基礎から応用まで学び直す:設計と活用事例
fumiyasac0921
0
150
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
237
140k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
Building Better People: How to give real-time feedback that sticks.
wjessup
368
20k
Automating Front-end Workflow
addyosmani
1371
200k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
860
Agile that works and the tools we love
rasmusluckow
331
21k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
45
2.5k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.1k
Building Applications with DynamoDB
mza
96
6.7k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
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つの行動)