定数、変数、データ型について
学習の目的
この単元を完了すると、次のことができるようになります。
- ネイティブの Swift の型を使用して数値、文字列値、Boolean 値を表す。
- 定数を使用する場合と変数を使用する場合を識別する。
- 定数と変数に値を割り当てる。
- クリーンなコードを記述するのに型推論がどのように役立つか説明する。
- 安全なコードを記述するのに型安全がどのように役立つか説明する。
アプリケーションの作成や一般的なプログラミングの大部分はデータの操作です。開発者は、明確に定義された型を使用するデータの処理方法と格納方法を理解する必要があります。型は、データを操作するための青写真のようなものです。
この単元では、後でプログラムで使用できるよう個々のデータを命名するために、定数と変数がどのように役に立つのかを学習します。変更されない値に定数を定義する方法と、変更される値に変数を定義する方法を学習します。
また、型についても学習します。定数または変数でさまざまな型を使用して格納できます。Swift に含まれている型と、より優れたコードを記述するのに Swift の型がどのように役立つかを学習します。
定数
プログラムの有効期間中に変更されない値を命名する場合は、定数を使用します。
Swift の定数は let
キーワードを使用して定義します。
let name = "John"
上記のコードは、name
と呼ばれる新しい定数を作成し、その定数に John という値を割り当てます。以降のコード行でその値にアクセスする必要がある場合は、name
を使用して定数を直接参照できます。この参照は、プログラム内で 1 つの値を何度も使用する場合に特に便利です。
let name = "John" print(name)
このコードでは、コンソールに John と出力されます。
name
は定数なので、これを割り当てた後に新しい値を指定することはできません。たとえば、次のコードはコンパイルされません。
let name = "John" name = "James"
変数
プログラムの有効期間中に変更される可能性のある値を命名する場合は、変数を使用します。
変数は var
キーワードを使用して定義します。
var age = 29 print(age)
上記のコードでは、コンソールに 29 と出力されます。
age は変数なので、以降のコード行で新しい値を割り当てることができます。次のコードはエラーもなくコンパイルされます。
var age = 29 age = 30 print(age)
このコードでは、コンソールに 30 と出力されます。
他の定数と変数から、定数と変数を割り当てることができます。この機能は、他の変数に値をコピーする場合に便利です。
let defaultScore = 100 var playerOneScore = defaultScore var playerTwoScore = defaultScore print(playerOneScore) print(playerTwoScore) playerOneScore = 200 print(playerOneScore)
コンソールには次のように表示されます。
100 100 200
定数か変数か?
値が変更されない場合には定数を使用し、値が変更される可能性がある場合には変数を使用することを学びました。
これには、知っておくべきニュアンスがあります。特定の値が変数であっても、コードを 1 回実行している間に変更されない場合は、定数として表すことができます。
たとえば、旅の移動距離に関する情報を計算するとします。プログラムを再使用して多数の旅を経時的に追跡することができますが、一度に追跡できる旅は 1 つだけです。次のデータをコードで表すには、どうしたらよいでしょうか?
- 出発地。これは、旅の出発地の GPS 座標です。プログラムで旅の追跡を開始したら、この位置が変更されることはありません。この値は定数で表します。
- 目的地。この GPS 座標は到着地です。アプリケーションでは多数の目的地を使用できるので、これは変数で表されると思うかもしれませんが、プログラムで旅の追跡を開始したら、目的地が変更されることはありません。この値は定数で表します。
- 現在地。現在地の GPS 座標は、移動するたびに変更されます。したがって、この値は変数で表します。
- 移動した距離。出発地からどれくらい移動したのでしょうか? この値は、移動すると変更されます。これは別の変数で表します。
- 残りの距離。目的地に着くまで、あとどれくらい移動する必要があるのでしょうか? 残りの距離は、移動すると変更されます。この値は変数で表します。
定数と変数は、非常によく似たジョブを実行します。すべてに変数を使用し、定数を完全に無視すれば簡単だろうと思われるかもしれません。厳密に言えば、そのやり方でもコードは機能します。そもそもなぜ定数を使用するのでしょうか?
1 つ目は、値を定数に設定すると、その値は変更されないものとしてコンパイラーで認識されるからです。つまり、定数の値を変更しようとすると、プログラムが作成または実行されません。このように、コンパイラーでは安全性が強化されています。
2 つ目は、コンパイラーで定数値に対して実行可能な特別な最適化があるからです。変更されない値に定数を使用すると、コンパイラーでは値の格納方法についての憶測が立てられます。この調整によってプログラムをより高速に実行できるようになります。
3 つ目は、このプロセスが Swift での慣用的なやり方だからです。
ソフトウェア構築についての知識がさらに深まると、一貫してクリーンで読みやすいコードを記述するためのベストプラクティスの真価が理解できるようになるでしょう。これは、他の開発者たちとチームで作業する場合には特に重要なことです。また、ベストプラクティスに従えば、特に後で変更を加える必要がある場合には、コードで実行されることを覚えておきやすくなります。
優れた開発者になるためには、共通のパターンと規則に従ってください。このモジュールでは、Swift を記述するためのベストプラクティスを説明していきます。
定数と変数の命名
定数と変数の命名にはルールがあります。コンパイラーでルールが適用されるので、ルールに従わなければプログラムを作成することも実行することもできません。ルールは次のとおりです。
- 名前に数学記号を含めることはできない。
- 名前にスペースを含めることはできない。
- 名前の先頭に数字は使用できない。
上記の 3 つのルールにさえ従えば、定数と変数は好きなように命名できます。
let π = 3.14159 let 一百 = 100 let 🎲 = 6 let mañana = "Tomorrow" let anzahlDerBücher = 15 //numberOfBooks
ルールの他に、定数と変数の命名の重要なベストプラクティスがあります。
- 定数と変数の名前は明確に内容を説明するものにし、後で戻って作業するときにコードを簡単に理解できるようにします。たとえば、
firstName
はn
より好ましく、restaurantsNearCurrentCity
はnearby
より好ましい名前です。 - 明確に内容を説明するために、名前には複数の単語を使用します。2 つ以上の単語を組み合わせる場合の規則は、キャメルケースを使用することです。つまり、名前の最初の文字を小文字にし、新しい各単語の最初の文字を大文字にします。
defaultScore
を例にとると、default
とscore
.の組み合わせがキャメルケースになっているのがわかります。キャメルケースを使用すると読みやすくなります。たとえば、defaultScore
はdefaultscore
よりわかりやすく、restaurantsNearCurrentCity
はrestaurantsnearcurrentcity
よりわかりやすくなります。
// Setting pi to a rough estimate let π = 3.14
コメントに複数の行が必要な場合、/* と */ の間にテキストを何文字でも入力できます。コメントは Swift コンパイラーで無視されます。
/* The digits of pi are infinite, so instead I chose a close approximation.*/ let π = 3.14
コメントは、コードの難解な部分を説明したり、ファイルの先頭に著作権情報を表示したり、日付情報 (ファイルの作成日や変更日) を提供したりするために、よく使用されます。
型
Swift の各型には、その型の定数または変数を使用するときに役立つプロパティと関数があります。プロパティはオブジェクトに関する情報を表し、関数はそのオブジェクトで何らかのアクションを実行します。
次に定義された簡単な Person
型について考えてみます。
struct Person { var firstName: String var lastName: String func sayHello() { print("Hello there! My name is \(firstName) \(lastName).") } }
上記のコードブロックにある構文に慣れていなくても問題はありません。これは型定義と呼ばれ、Person
型のプロパティと関数を定義します。
型定義は、どのようにオブジェクトが表示され、機能するのかを示す青写真と考えてください。この例では、Person
型のオブジェクトがどのように表示され、機能するのかを説明します。
コードを読むと、firstName
と lastName
という 2 つの String
値があるのがわかります。これらはプロパティと呼ばれ、その人物に関する情報が格納されます。また、sayHello()
とありますが、これはその人物に対するアクションを定義する関数です。
新しい変数を作成するたびに、型のインスタンスが作成されます。次のコードについて考えてみます。
let aPerson = Person(firstName: "Jacob", lastName: "Edwards") let anotherPerson = Person(firstName: "Candace", lastName: "Salinas") aPerson.sayHello() anotherPerson.sayHello()
これは、次のように出力されます。
Hello there! My name is Jacob Edwards. Hello there! My name is Candace Salinas.
このコードでは、Person
型のインスタンスが 2 つ作成されます。1 つのインスタンスは、Jacob Edwards という Person
を表し、もう 1 つのインスタンスは、Candace Salinas という人物を表します。
Swift には、クリーンなコードを記述しやすくする定義済みの型が多く用意されています。プログラムに数値、文字列値、または Boolean (true/false) 値を含める必要がある場合、型を使用して特定の情報の種類を表すことができます。
Swift でよく使われる型は次のとおりです。
型名 |
記号 |
目的 |
例 |
Integer |
Int |
整数を表す |
4 |
Double |
Double |
小数点を必要とする数値を表す |
13.45 |
Boolean |
Bool |
true 値または false 値を表す |
true |
文字列 |
String |
テキストを表す |
“Once upon a time ...” |
Swift では、複数のインスタンスを 1 つの変数にグループ化するコレクション型もサポートされます。コレクション型の 1 つは Array
と呼ばれ、オブジェクトの順序付きリストが格納されます。もう 1 つのコレクション型は Dictionary
と呼ばれ、特定の値の検索に役立つキーを持ちます。コレクション型を使用して、複数のオブジェクトを 1 つの定数または変数に格納できます。
Swift 標準ライブラリには前述の型がすべて含まれており、いつでも使用できます。
さらに Swift では、Person
の例と同じ構造を使用して独自の型を定義できます。
型安全
Swift は型安全な言語とみなされています。型安全な言語では、コードで操作できる値の型を明確にすることが推奨または要求されます。たとえば、Int
を期待する関数では、Double
または String
に値を渡すことができません。
コードをコンパイルしているときに、Swift ではすべての定数と変数の型チェックが行われ、一致しない型にはエラーのフラグが付けられます。型が一致しなければ、プログラムは実行できません。
let playerName = "Julian" var playerScore = 1000 var gameOver = false playerScore = playerName // Will be flagged for mismatched types, will not compile.
型安全では、どの型を使用するのか注意する必要があります。上記の例は明らかに一致していません。Int
変数に String
値を割り当てても意味がありません。playerScore
にアクセスするときに期待されるのは、テキストではなく数値で表されたスコア値です。
型安全は、互換性があるように思われるデータを表す値にも適用されます。たとえば、Int
と Double
はどちらも数値を表すにもかかわらず、コンパイラーではまったく異なる型として認識されます。
var wholeNumber = 30 var numberWithDecimals = 17.5 wholeNumber = numberWithDecimals // Will be flagged for mismatched types, will not compile.
上記のケースでは、どちらの変数も数値ですが、wholeNumber
は Int
で、numberWithDecimals
は Double
になります。Swift では、ある型の値を別の型の変数に割り当てることができません。
数値を使用するときに、変数または定数に非常に大きな値を割り当てる必要があることがあります。1000000000 に何個のゼロがあるのか確認しづらいので、読みにくい場合があります。幸い、Swift では、読みやすい形式にする方法として、数値にアンダースコアを入れることができます。
var largeUglyNumber = 1000000000 var largePrettyNumber = 1_000_000_000
型推論
定数または変数を宣言するときに、値の型を指定する必要がないことがあります。これを型推論と呼びます。Swift では型推論を使用して、定数または変数に割り当てられた値に基づいて型の憶測が立てられます。
let cityName = "San Francisco" // "San Francisco" is obviously a `String`, so the compiler // automatically assigns the type of cityName to a `String`. let pi = 3.1415927 // 3.1415927 is a number with decimal points, so the compiler // automatically assigns the type `pi` to a `Double`.
値を定数または変数に割り当てると型が設定され、変更はできません。これは変数でも同じです。変数の値は変更できますが、その型は変更できません。
定数または変数の型を明示的に指定すると便利、または必要でさえあるケースがあります。これを型アノテーションと呼びます。型を指定するには、コロン (:
)、スペース、型名の後に、定数名または変数名を追加します。
let cityName: String = "San Francisco" let pi: Double = 3.1415927
型アノテーションは、異なる数値型で使用できます。Swift コンパイラーで、型と一致するように値が調整されます。
let number: Double = 3 print(number)
この場合、3.0
と出力されます。
型アノテーションの使用には、一般的に 3 つのケースがあります。
1.定数または変数を作成したが、それにまだ値が割り当てられていない場合
let firstName: String //... firstName = "Layne"
2.複数の型として推定される可能性がある定数または変数を作成する場合
let middleInitial: Character = "J" // "J" would be inferred as a `String`, but we want a `Character` var remainingDistance: Float = 30 // `30` would be inferred as an `Int`, but the variable should support decimal numbers for accuracy as the number decreases.
3.独自の型定義を記述する場合
struct Car { var make: String var model: String var year: Int }
必須の値
定数または変数を定義するときに、型アノテーションを使用して型を指定するか、コンパイラーで型の推定に使用できる値を割り当てる必要があります。
var x // This would result in an error.
型アノテーションを使用しても、まだ値が割り当てられていない定数または変数をコードで使用することはできません。
var x: Int print(x) // This would result in an error.
値を割り当てたら、定数または変数を使用できるようになります。
var x: Int x = 10 print(x)
ラボの終了
Swift を実際に使ってみる準備はできていますか? 課題で学習したことを Lab - Constants and Variables.playground で練習してください。