より多くは、フロントエンド開発者の視点から、2 つの言語の違いを比較し、より便利に入門できるようにすることです。
基本型(DataType)#
ほとんどの場合、基本型は言語の最底層の実装を直接表します。
JavaScript は弱い型付けで、基本データ型は以下の 7 種類です:
- String
- Number
- BigInt
- Boolean
- Symbol (ECMAScript 2016 で追加)
- null
- undefined
Rust は静的型 ( statically typed ) 言語であり、コンパイル時にすべての変数の型を知っている必要があります。すべての値は特定のデータ型 ( data type ) に属し、Rust にそのデータがどのようなデータであるかを知らせ、データ処理の方法を明確にします。基本的には 2 つのデータ型のサブセットに属します:スカラー(scalar)と複合(compound)。
整数型(Integer)
ビット長 | 符号付き | 符号なし |
---|---|---|
8 ビット | i8 | u8 |
16 ビット | i16 | u16 |
32 ビット | i32 | u32 |
64 ビット | i64 | u64 |
128 ビット | i128 | u128 |
アーキテクチャ | isize | usize |
各符号付きの変種は、$-(2^{n-1})$ から $2^{n-1}-1$ までの数字を格納できます。ここで $n$ は変種が使用するビット数です。したがって、i8
は $-(2^7)$ から $2^7-1$ までの数字を格納でき、つまり $-128$ から $127$ までです。符号なしの変種は $0$ から $2^n-1$ の数字を格納できるため、u8
は $0$ から $2^8-1$ までの数字を格納でき、つまり $0$ から $255$ までです。
注意:以下の表のいずれかの形式で数字リテラルを記述できます。数字リテラルは複数の数字型を持つことができ、型サフィックスを使用して型を指定することができます。例えば、57u8
のように、_
を区切り文字として使用して読みやすくすることもできます。例えば、1_000
は指定した 1000
と同じ値です。
整数の表現方法
基数 | 例 |
---|---|
十進法 | 98_222 |
十六進法 | 0xff |
八進法 | 0o77 |
二進法 | 0b1111_0000 |
バイト(u8 型のみ) | b'A' |
浮動小数点数型(Floating-Point Number)
浮動小数点数は小数点を持つ数字です。Rust の浮動小数点数型はf32
とf64
で、それぞれ 32 ビットと 64 ビットを占めます。デフォルトの型はf64
で、現代の CPU ではf32
とほぼ同じ速度ですが、精度が高いです。すべての浮動小数点型は符号付きです。
ブール型(Bool)
識別子:bool
- true
- false
文字型(Char)
単一引用符は文字型 (char) を示し、二重引用符は文字列 (str) を宣言します。
Rust のchar
型のサイズは 4 バイトであり、Unicode スカラー値(Unicode Scalar Value)を表します。これは、ASCII よりも多くの内容を表すことができることを意味します。Rust では、アクセント付き文字、中国語、日本語、韓国語などの文字、絵文字(emoji)、およびゼロ長の空白文字が有効なchar
値です。Unicode スカラー値は、U+0000
から U+D7FF
および U+E000
から U+10FFFF
までの値を含みます。ただし、「文字」は Unicode の概念ではないため、人間の直感的な「文字」は Rust のchar
とは一致しない場合があります。
複合型(Compound types)
Rust には 2 つのネイティブな複合型があります:タプル(tuple)と配列(array)。
- タプルは、複数の他の型の値を 1 つの複合型に組み合わせる主要な方法です。
- タプルの長さは固定されており、一度宣言されると、その長さは増減しません。
- 配列の各要素の型は同じでなければなりません。
- Rust の配列の長さは固定されています。
その他
- ベクター(
Vec<T>
)- 可変長配列
- ベクターは、単一のデータ構造内に複数の値を格納することを可能にし、メモリ内で隣接してすべての値を配置します。
- 文字列(String)
- 文字列はバイトの集合といくつかのメソッドによって実現されています。
String
という型は標準ライブラリによって提供され、コア言語部分には書かれておらず、可変で、所有権があり、UTF-8 エンコードされた文字列型です。
- マップ(
HashMap<K, V>
)- これはハッシュ関数(hashing function)を使用してマッピングを実現し、キーと値をメモリにどのように配置するかを決定します。多くのプログラミング言語はこのデータ構造をサポートしていますが、通常は異なる名前で呼ばれます:ハッシュ、マップ、オブジェクト、ハッシュテーブル、または連想配列など。
- ハッシュマップは、ベクターのようにインデックスを使用するのではなく、任意の型をキーとしてデータを検索する必要がある場合に使用できます。
変数(Variables)#
var code = 123; // 古いバージョンの規格では、varキーワードを使って宣言するだけでよい
let firstName = "kaby"; // ES6以降、letは変数を示し、変更を許可する
const lastName = "Zhao"; // ES6以降、constは定数を示し、変更を許可しない
firstName = "bike"; // 正常
lastName = "Hu"; // エラー - Uncaught TypeError: Assignment to constant variable
// Rustのすべての変数はデフォルトで変更を許可しません。例えば
let code = 123;
println!("codeの値は: {code}"); // 正常
code = 456; // エラーをスロー - cannot assign twice to immutable variable `code`
// 変更可能な変数を宣言する
let mut name = "lulu";
println!("名前は: {name}"); // luluを出力
name = "jack";
println!("名前は: {name}"); // jackを出力
// 定数を宣言するためのキーワードも同様に使用できます
// 定数にmutを使用することはできません
// 定数はデフォルトで変更できないだけでなく、常に変更できません
const WAIT_SEC:u32 = 30;
// 変数の隠蔽
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
// 12
println!("内側のスコープでのxの値は: {x}");
}
// 6
println!("xの値は: {x}");
}
関数 & ロジック#
// メソッドの宣言
function getName() {
return "jack";
}
// 変数を通じて
let getInfo = function() {
return {
"age": 18
}
}
// 上記はアロー表記でも使用できます
let getInfo = () => ({ "age": 18 })
// ロジック
// if / switchによる判断
if (getName() == "jack") {
return "lose";
} else if (getName() == "lose") {
return "moth";
} else {
return "";
}
// ループ for...in / for...of / while
let arr = [1, 2, 3];
for(let i = 0; i < arr.length; i++) {
console.info(i);
}
// JavaScriptは弱い型付け言語であるため、変数の型を自動的に推測し変換します。
// そのため、比較や判断が比較的簡単で、直接==を使用できます。
// ただし、意外な状況が発生することもあります。例えば、
// "5" == 5 の結果は true です。ここは注意が必要で、"5" === 5 で解決できます。
// また、文字列が等しいかどうかを直接判断することもできます。
// "abc" == "cde"
// メソッド
fn main() {
println!("hello world");
another_function();
// print_labeled_measurement
print_labeled_measurement(5, 'h');
// plus_one
let po = plus_one(8);
// po == 9
println!("計算結果は {}", po);
// logic_info関数を実行
logic_info("abc", 12);
// ループ
loop_info();
}
// another_function
fn another_function() {
println!("another_function");
}
// 引数を持つメソッド
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("測定値は: {value}{unit_label}");
}
// このメソッドに戻り値がある場合は、戻り値の型も定義する必要があります
fn plus_one(x: i32) -> i32 {
return x + 1;
}
// ロジック判断
fn logic_info(name: &str, age: i32) {
println!("{} の年齢は {} ", name, age);
// 数字型の場合、ifを使って直接比較できます
if age > 12 {
println!("12歳以上、切符を購入する必要があります");
} else if age < 12 {
println!("無料で乗車できます");
} else {
println!("12歳、切符を購入する必要があります");
}
// 文字列の比較
if name == "lulu" {
println!("こんにちは, {}", name);
} else {
println!("名前が一致しません");
}
}
// ループ
fn loop_info() {
// whileループ
let mut number = 3;
while number != 0 {
println!("{number}!");
number -= 1;
}
println!("LIFTOFF!!!");
// forループ
let a = [10, 20, 30, 40, 50];
for element in a {
println!("値は: {element}");
}
// loopループ
// 注意、loopループは自動的に終了せず、手動でbreakが必要です
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("loopループの結果は: {result}");
}
// 具体的なコードはここで確認できます
// https://play.rust-lang.org/?gist=e87ef95f861dbc22bf8f23722e40aa34