1.1 値とは何か
プログラムは、基本的には値を受け取り、変換し、別の値を返す仕組みです。
入力値 → 処理 → 出力値
代表的な値には次があります。
整数
小数
文字列
真偽値
配列
オブジェクト
関数
null相当値
言語ごとに構文は違っても、扱っている概念は共通です。
$count = 10;
count = 10
let count = 10;
いずれも「整数値10に名前countを与える」という処理です。
1.2 型とは何か
型は、値についての制約や性質を表します。
例えば整数型には、次のような意味があります。
この値は整数である
整数として演算できる
文字列専用の操作はできない
型には大きく二つの役割があります。
値の解釈
同じビット列や文字列でも、型によって意味が変わります。
"10" → 文字列
10 → 整数
10.0 → 浮動小数点数
使用可能な操作の制限
整数 + 整数
文字列 + 文字列
オブジェクト.メソッド()
型システムは、「その値にどの操作を許可するか」を決める規則です。
1.3 静的型付けと動的型付け
静的型付け
プログラムを実行する前に、型の整合性を検査します。
代表例:
Rust
Java
C#
Go
Swift
Kotlin
TypeScript
Rustでは次のコードはコンパイルできません。
let number: i32 = 10;
let result = number + "20";
整数と文字列を加算しようとしているためです。
動的型付け
実行時に値の型が判断されます。
代表例:
Python
PHP
JavaScript
Ruby
Pythonでは、変数そのものに固定型が付くというより、変数が値を参照します。
value = 10
value = "hello"
同じ名前が、後から異なる型の値を参照できます。
ただし、動的型付けでも「型がない」わけではありません。値には型があります。
type(10) # int
type("hello") # str
違いは、いつ型を検査するかです。
1.4 強い型付けと弱い型付け
静的・動的とは別の軸として、暗黙の型変換をどの程度許すかがあります。
JavaScriptでは次が成立します。
"10" + 20
// "1020"
文字列に合わせて数値が文字列へ変換されます。
Pythonではエラーになります。
"10" + 20
# TypeError
どちらも動的型付けですが、暗黙変換に対する方針が異なります。
したがって、次の二軸は区別する必要があります。
| 軸 | 問い |
|---|---|
| 静的/動的 | 型をいつ検査するか |
| 強い/弱い | 異なる型をどこまで暗黙変換するか |
「強い型付け」「弱い型付け」には厳密な統一定義がないため、実務では具体的に「どの変換を暗黙に許すか」を確認する方が適切です。
1.5 型推論
静的型付け言語でも、毎回型を書く必要があるとは限りません。
let count = 10;
Rustコンパイラはcountの型を推論します。
const count = 10;
TypeScriptでもnumberと推論されます。
明示的にも書けます。
let count: i32 = 10;
const count: number = 10;
型推論とは、型をなくすことではありません。コンパイラが型を導出する仕組みです。