Rustさわる
UP NEXT:
TODO: Concurrencyわかりにくめ
enumが TypeA | TypeB | TypeC 的に使える&データも入れられて便利
モジュールシステム
ディレクトリ名とモジュール名を勝手にリンクさせるのでimportにあたるものを書かなくて良い
よさげ
Similarly, the unwrap and expect methods are very handy when prototyping, before you’re ready to decide how to handle errors. They leave clear markers in your code for when you’re ready to make your program more robust.
コンパイラがとてもかしこい
トレイトオブジェクト:
振る舞いを実装していれば、型はダイナミックでよい
トレイトオブジェクトは、 指定したトレイトを実装するある型のインスタンスを指します。
ただし、実行時に型情報は失われているので オブジェクト安全
であることが必要。
オブジェクト安全:
戻り値の型がSelfでない。
ジェネリックな型引数がない。
ダイナミックディスパッチが行われるため、コンパイラによる最適化は(一部)行われない。
(柔軟な処理の代償)
pub struct Screen {
pub components: Vec<Box<Draw>>,
}
largest
を参照を返すように書き換える
// borrows a slice
fn largest<T: PartialOrd>(list_ref: &[T]) -> &T {
let mut largest_element_ref = &list_ref[0];
// borrows item_ref
for item_ref in list_ref {
if item_ref > largest_element_ref {
largest_element_ref = item_ref;
}
}
largest_element_ref
}
かしこい
ワークスペースには、各クレートのディレクトリそれぞれにCargo.lockが存在するのではなく、 ワークスペースの最上位階層にただ一つのCargo.lockが存在するだけのことに注目してください。 これにより、全クレートが全依存の同じバージョンを使用していることが確認されます。 randクレートをadder/Cargo.tomlとadd-one/Cargo.tomlファイルに追加すると、 Cargoは両者をあるバージョンのrandに解決し、それを一つのCargo.lockに記録します。 ワークスペースの全クレートに同じ依存を使用させるということは、 ワークスペースのクレートが相互に互換性を常に維持するということになります。
クラシックな例が登場した
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
fn main() {
let list = Cons(1,
Box::new(Cons(2,
Box::new(Cons(3,
Box::new(Nil))))));
}
Deref
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> {
MyBox(x)
}
}
use std::ops::Deref;
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}