この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:atom
更新日時:2026-06-12 15:30:23

タイトル: 定数の宣言
SEOタイトル: Swiftで定数を宣言する方法|letとvarの違いと使い分け

Swiftで定数を宣言するには、let キーワードを使って let 定数名 = 値 と書く。let で宣言した値は一度代入すると後から再代入できず、変化しないことが保証される。

たとえば次の一行で、文字列の定数 message を宣言できる。

let message = "Hello, Swift"

print(message)  // Hello, Swift

 

この記事の要点
  • 定数は let、変数は var で宣言する。再代入が不要な値は基本的に let を選ぶ。
  • 書式は let 名前 = 値。型は初期値から推論されるため、多くの場合は型注釈を省略できる。
  • 型を明示したいときは let 名前: 型 = 値 のように、コロンに続けて型注釈を書く。
  • let を優先すると、意図しない再代入をコンパイル時に防げて、安全性と可読性が高まる。
  • let で束縛できないのは「再代入」だけ。参照型(class)のインスタンスでは、内部の可変プロパティは変更できる。
  • 宣言時に値を与えず、後で一度だけ代入する遅延的な初期化も let で行える。

 

let(定数)と var(変数)の違い

Swiftでは、値に名前を付ける方法として letvar の2つがある。let定数を宣言し、一度代入した値を後から変更できない。var変数を宣言し、後から別の値を再代入できる。

let pi = 3.14159    // 定数(再代入できない)

var count = 0      // 変数(再代入できる)

count = 1          // OK:var なので変更できる

// pi = 3.14       // エラー:let は再代入できない

どちらを使うか迷ったときは、まず let で書き始め、後から値を変える必要が出てきたら var に変える、という進め方が一般的とされる。値が変わらないことが型システム上で保証されるため、コードの意図が読み手に伝わりやすくなる。

 

let の宣言と型注釈

もっとも基本的な書式は let 名前 = 初期値 で、初期値から型が自動的に推論される。下の例では、titleStringyearInt と推論される。

let title = "Swift Guide"   // String と推論される

let year = 2024            // Int と推論される

型を明示したい場合は、定数名の後にコロンと型を書く。これを型注釈と呼ぶ。リテラルの既定の型とは別の型を使いたいときや、初期値を後から与えるときに役立つ。

let rate: Double = 5     // 5 を Double として扱う(5.0)

let initial: Character = "S" // String ではなく Character

複数の定数を一行で宣言することもできる。読みやすさを保てる範囲で使うとよい。

let x = 0, y = 0, z = 0

 

なぜ定数(let)を優先するのか

変えるつもりのない値を let で宣言しておくと、いくつかの利点が得られると説明されることが多い。

  • 安全性:後から誤って値を書き換えるコードを書いても、コンパイル時にエラーになって気付ける。実行してから初めて不具合に気付く、という事態を減らせる。
  • 最適化:値が変化しないことがコンパイラに伝わるため、最適化の手がかりになり得る。実際の効果はコードやコンパイラに依存するが、不変であるという情報自体は無駄にならない。
  • 意図の明示let と書かれているだけで「この値はこの先変わらない」という設計意図が読み手に伝わる。コメントに頼らずに不変性を表現できる。

こうした理由から、Appleの公式ドキュメントでも、値を変える必要がない場合は let で宣言することが推奨されている。

 

let は再代入不可だが、参照型の中身は変えられる

注意したいのは、let が固定するのは「その定数が指し示す対象そのもの(束縛)」であって、対象の内部状態すべてではない、という点である。

値型(structenumIntString・配列など)を let で宣言した場合は、プロパティの変更も含めて一切変更できない。一方、参照型(class)を let で宣言した場合、その定数が別のインスタンスを指すように付け替えることはできないが、指しているインスタンスの内部にある可変プロパティ(var)は変更できる

class Counter {

    var value = 0

}

 

let counter = Counter()

counter.value = 10    // OK:参照先の可変プロパティは変更できる

// counter = Counter() // エラー:別インスタンスへの付け替えはできない

同じことを struct(値型)で書くと、let 宣言ではプロパティの変更もエラーになる。「中身を変えたい」場合は var で宣言する必要がある。この違いは値型と参照型の性質に由来する。

 

let と計算プロパティ・定数式の違い

let は「一度だけ値を保持して再代入を禁じる」しくみであり、初期値は宣言時に決まる。これに対し、アクセスのたびに値を計算して返す計算プロパティ(computed property)var で宣言し、get によって毎回値を求める。両者は目的が異なる。

struct Circle {

    let radius: Double         // 格納する定数

    var area: Double {       // アクセスのたびに計算

        radius * radius * Double.pi

    }

}

また、初期値が単純なリテラルや、コンパイル時に決まる固定値であっても、Swiftの let は「実行時に一度だけ評価する定数」である点に注意する。多くの場合この区別を意識する必要はないが、let は必ずしも他言語の「コンパイル時定数」と同義ではない。

 

letvar の比較

項目 let(定数) var(変数)
再代入 できない(束縛は固定) できる
主な用途 変化しない値、設定値、一度だけ決まる値 カウンタや状態など、変化する値
意図の明示 不変であることがコードで伝わる 変化し得ることを示す
参照型の内部変更 可変プロパティは変更できる 変更できる
選び方の目安 まずこちらを優先 再代入が必要になったとき

 

落とし穴と注意点

ケース 内容と対処
let への再代入 代入済みの let に再び代入すると「Cannot assign to value」などのコンパイルエラーになる。値を変える必要があるなら var に変更する。
遅延的な初期化 let は宣言と同時に値を与えなくてもよい。条件分岐などで後から「一度だけ」代入する形も許される。ただし使用前に必ず初期化されている必要がある。
参照型の可変性 let で宣言した class のインスタンスは、内部の var プロパティを変更できる。「let だから中身も不変」と思い込むと想定外の変更を見落とす。完全に不変にしたい場合は struct を使う、プロパティも let にするなどの設計を検討する。
未使用の var 再代入していない var があると、コンパイラが「let にできる」と警告することがある。意図がなければ let に直すとよい。

遅延的な初期化の例を示す。次のコードは let でも問題なくコンパイルできる。

let label: String

if isActive {

    label = "有効"

} else {

    label = "無効"

}

// label はこの後で一度だけ代入され、以降は変更できない

 

よくある質問(FAQ)

Q1. letvar はどちらを使えばよいですか。
A. 値を後から変える必要がなければ let を選ぶのが基本とされる。再代入が必要になった時点で var に変えるとよい。let を優先すると、意図しない変更をコンパイル時に防げる。

Q2. let で宣言した class のインスタンスのプロパティを変更できるのはなぜですか。
A. let が固定するのは「その定数がどのインスタンスを指すか」という束縛だけだからである。class は参照型なので、指しているインスタンス内部の var プロパティは変更でき、別インスタンスへの付け替えだけが禁止される。

Q3. 型注釈は省略してもよいですか。
A. 初期値があれば型は推論されるため、多くの場合は省略できる。Double として扱いたい整数リテラルなど、推論される型と使いたい型が異なるときや、初期値を後から与えるときは型注釈を書く。

Q4. let で宣言と同時に値を入れないとエラーになりますか。
A. 必ずしもエラーにはならない。宣言時に初期値を与えず、後から一度だけ代入する書き方も認められている。ただし、値を使う前に初期化が完了している必要がある。