Rust を勉強してみた!
ssmylh
2017/09/02 開発合宿at 鳴子温泉
はじめに
Rust はまだ数時間しか勉強してません。理解が浅いです。誤解や間違っているところはあると思います。
モチベーション
せっかくのまとまった時間があるので何か新しい事がしたかった。独特だと聞いていて、なんとなく気になっていた。当初、 をテーマとしていたが、いつの間にかこっちに。WASM
Rust ?
速度、安全性、並行性の3つのゴールにフォーカスしたシステムプログラミング言語ゼロコスト抽象化ムーブセマンティクス保証されたメモリ安全性データ競合のないスレッドトレイトによるジェネリクス...
こんな感じ
fn fizzbuzz(n: s) {
for i in 0..n {
if i % 15 == 0 {
println!("FizzBuzz");
} else if i % 3 == 0 {
println!("Fizz");
} else if i % 5 == 0 {
println!("Buzz");
} else {
println!("{}", i);
}
}
}
こんな感じ
fn even_squre_sum(n: isize) -> isize {
(0..n)
.filter(|i| i % 2 == 0)
.map(|i| i * i)
.sum()
}
let expected = 4 + 16 + 36;
assert_eq!(even_squre_sum(7), expected);
こんな感じなんですが、今日は特に興味を持った
以下の機能について発表したいと思います。
所有権システムトレイト
所有権システム
所有権システム
メモリ安全性、ゼロコスト抽象化独特!!以下の3つの概念から成り立つ。所有権借用ライフタイム
所有権
値は資源であり、値を所有出来るのは一人の所有者のみ。変数束縛= 値の所有権を持つ。所有権は移動する(ムーブする)。(スコープから外れて)所有されていない状態になると、値は解放される。Copyな値は割り当て時にコピーされるので所有権の対象外。各種プリミティブな値はCopyな値。
所有権- 例
fn main() {
let x = "x".to_string();
let y = x;
// 以下 y 所有権
//println!("{}", x);
// 以下 関数 最後 str 外 時 値 解放
print(y);
// print 所有権
//println!("{}", y);
}
fn print(str: String) {
println!("{}", str);
}
所有権の例外(Copyな値) - 例
fn main() {
let x: i32 = 1;
let y = x;
// i32 Copy 実装
// y 割 当 時 作成 所有権
// 全 型 Copy 実装
println!("{}", x);
}
借用
所有権を持ったまま、値を他に貸し出す。ある型の参照型は、その型の借用と言う。イミュータブルな参照とミュータブルな参照がある。イミュータブルな参照は複数存在可能。ミュータブルな参照は同時に1つのみ。データ競合が発生しない。イミュータブルとミュータブルな参照は共存出来ない。値が解放された後には、その値は借用出来ない。
借用- 例1
fn immutable_reference() {
// 参照 同時 複数存在可能
let x = "x".to_string();
let y = &x;
let z = &x;
}
fn mutable_reference() {
// 参照 同時 1 存在可能
let mut x = "x".to_string();
let y = &mut x;
//let z = &mut x; // 2 目
}
借用- 例2
fn use_resource_after_frees() {
let a: &i32;
{
let x = 1;
// x 生存期間 超 借用 出来 以下
//a = &x;
}
}
ライフタイム
参照が有効なスコープを記述する仕組み。ダングリングポインタを仕組み的に防ぐ。ブロックスコープや関数スコープによりライフタイムが区切られる。
ライフタイム- 例
// 参照 持 構造体 明示的 ( 'a ) 必須
// 参照 構造体自体 参照 生存期間 長 必要
struct Misc<'a> {
x: &'a i32,
}
fn main() {
let a: &i32;
{
let y = &1;
let m = Misc { x: y };
// 以下 許可
// a 外 値 参照
//a = m.x;
}
}
トレイト
トレイト
Rust のトレイトは型クラス。アドホックポリモーフィズム既存の型に共通のインターフェイスを持たせられる。
トレイト- 定義
trait Semigroup<T> {
fn append(&self, that: T) -> T;
}
trait Monoid<T>: Semigroup<T> {
fn zero() -> T;
}
impl Semigroup<i32> for i32 {
fn append(&self, that: i32) -> i32 {
*self + that
}
}
トレイト- 実装
impl Monoid<i32> for i32 {
fn zero() -> i32 {
0
}
}
fn main() {
let v1 = (1.append(2)).append(3);
let v2 = 1.append(2.append(3));
assert_eq!(v1, v2);
// self 引数 取 型名:: 名() 呼 出 可能
let zero = i32::zero();
assert_eq!(1.append(zero), 1);
assert_eq!(zero.append(1), 1);
}
感想
新しい要素を持った言語を学ぶのは楽しい。もっとRustを勉強してみたくなった。特に平行処理関連。
今日のコード
https://github.com/ssmylh/try_rust
参考にしたもの
最速で知る!プログラミング言語Rustの基本機能とメモリ管理【第二言語としてのRust】プログラミング言語Rust
Rust by Example

Rustを勉強してみた!