Open7

TypeScript書いたことある自分がRustを学んでいるときのメモ

k4nd4k4nd4

変数宣言はletを使う。

TypeScriptだとletは再代入できるけどconstは再代入できない、という違いがあった。
Rustの場合、letで宣言したものは基本的に再代入不可。

let num = 0;

num = 1; // これができない

変更したい場合はletの後にmutをつける。

let mut num = 0;

num = 1; // OK

変更できないことをimutableと表現し、変更できることをmutableと表現する。
(単なる英単語の話だが、この言葉自体はRustでよく出てくる)

k4nd4k4nd4

JS / TSにおけるオブジェクトは、Rustではstruct(構造体)として表現する。

TS
type Person = {
  name: string;
  age: number;
}
Rust
struct Person {
    name: &'static str,
    age: i32,
}

&'staticは、文字列の参照のライフタイムというやつらしい。
Rustにおいて文字列は参照型として持ち、さらに参照はライフタイムが厳密に管理される(?)ため、構造体の中で文字列を持たせたい場合はこうなるらしい。よくわかってない。

k4nd4k4nd4

関数の宣言はfnで始める。戻り値の型は->で表現する。

TS
const add = (x: number, y: number): number => {
  return x + y;
}
Rust
fn add(x: i32, y: i32) -> i32 {
  return x + y;
}
k4nd4k4nd4

Rustでは関数の最後にreturnが不要。

Rust
fn add(x: i32, y: i32) -> i32 {
  x + y
}

厳密にいえば、{}で囲まれたブロックの最後の行がセミコロン;で終了していない場合、その行の評価結果がブロック全体の評価結果になる。

Rust
fn main() {
    let x = {
      let y = 1;
      let z = 2;
      y + z
    };
    
    println!("{}", x); // 3
}

上記の例でいえば、y + zの行にセミコロンをつけてしまうとうまく動かないし、逆にlet ylet zの行にセミコロンをつけてもダメ。

k4nd4k4nd4

TypeScriptでいうundefinedみたいなものはOptionというものを使えば可能。

TypeScript
const foo = (): number | undefined => {
    //
}
Rust
fn foo() -> Option<u32> {
    //
}

なにか決まった値を返すのであればSome(値)とし、そうでないなら(TSでいうundefinedNoneとする。

k4nd4k4nd4

TypeScriptでは、標準が提供するenumの代わりにオブジェクトを使うことがよくある。

TypeScript
const MESSAGE_ID = {
  HOGE: 'HOGE',
  FUGA: 'FUGA',
} as const;

Rustではちゃんとしたenumがあるのでそれを使う。

Rust
enum MessageId {
  Hoge,
  Fuga,
}