【Swift】コードを効率良く書くために必要な知識をご紹介!初心者向けにわかりやすく解説
投稿日:2025/03/23
最終更新日:2026/03/20
Swiftの基本的な文法や構文を学び、簡単なiOSアプリを作れるようになったものの、「コードの書き方が最適なのか分からない」「アプリの構造が複雑になってきた」と感じたことはありませんか。
今回の記事では単に動作するアプリを作るだけでなく、可読性や保守性を意識したコード設計や、パフォーマンスを考慮した実装を理解することが重要になります。
Optionalの扱い方の応用、クロージャやプロトコルの活用、画面遷移やデータ管理を効率化する考え方などを今回は覚えておきたいテクニックを分かりやすく解説します。
実務や個人開発で役立つ知識を身につけることで、より完成度の高いiOSアプリ開発が可能になります。
Swiftを「書ける」段階から「設計を意識して使いこなせる」レベルへとステップアップしたい方は、ぜひ参考にしてください。
今回の記事では以下の項目について解説します。
- SwiftでのOptionalについて
- ジェネリクスについて
- エラーハンドリングについて
目次
Optional:if let・guard letの使い方
OptionalはSwiftの安全性を支える重要な概念であり、使い分けの理解が品質の高いコードを書くために重要となってくる概念です。if letはOptionalを一時的にアンラップし、条件分岐の中で安全に値を扱いたい場合に適しています。
そもそもOptionalとは
「値が存在しない状態である(nil)を安全に処理するための変数」です。
また値がない状態のことを「nil」と言います。
Yama
データのやり取りをアプリに実装したい場合にnilを受け取る可能性は十分にあります。
ではこのOptionalをどのように利用するのか?
これらが一体どういった意味を持っているのかをコードの例を用いて説明します。
「Optionalの使い方」
//Optionalの定義の仕方
var score: Int?
//Optionalに値を入れる方法
score = 100
「重要ポイント」
Optionalは「アンラップ」という方法を使う必要があります。
「アンラップ」
以下のようにコードを組み立てることで、値がある時だけ実行されます。
if let unwrappedScore = score {
print(unwrappedScore)
}
「強制アンラップ」
「!」をつけることで強制的にアンラップすることを試みることができますが、このOptionalに値がなかった場合、クラッシュしてしまうことになります。
しかし強制アンラップは「絶対にnilではない」と断言できる場合のみ使用します
//値が入っていない場合、クラッシュしてしまう
print(score!)
「if let」と「guard let」の使い方
「if let」は値が存在する場合のみ使用できます。
つまり値が存在する前提でコードを書くのに最適です。
「guard let」は値が存在しないということをメインにコードを書き進めます。
Yama
iOSアプリ開発においてのデータの受け取りの際にこの動作は必ず必要です。
以下が「if let」と「guard let」のコード例です。
if let
var age: Int? = 50
if let unwrappedAge = age {
print("私は\(unwrappedAge)です")
}else{
print("年齢は公開していません")
}
guard let
func getAge(age: Int?) {
guard let unwrappedAge = age else {
print("年齢は非公開です")
return
}
print("年齢は \(unwrappedAge) です")
}
処理範囲が限定されるため、ローカルなロジックに向いています。一方guard letは早期リターンを前提とし、値が存在しない場合に処理を中断する用途で使われます。
関数の冒頭で前提条件を明示できるため、可読性が高く、ネストを避けたコードを書ける点が利点です。
それぞれの特徴を理解し、処理の流れや可読性を意識して使い分けることで、Swiftらしい安全で洗練されたコードが実現できます。
ジェネリクス入門:再利用性の高いコードを書くための型設計
ジェネリクスは、型に依存しない柔軟な処理を実現するための仕組みであり、再利用性の高いコードを書くうえで欠かせない概念です。
通常、特定の型ごとに関数やクラスを定義すると、似た処理が重複しやすくなりますが、ジェネリクスを用いれば共通ロジックを1つにまとめられます。
Yama
共通ロジックを1つにまとめられることで圧倒的な効率化が可能となります。
以下がジェネリクスを是非使いたい例です。 同じロジックであるのにも関わらず同じことを3回も書いてしまっています。
func showAge(value: Int) -> Int {
return value
}
func showName(value: Int) -> Int {
return value
}
func showHeight(value: Int) -> Int {
return value
}
ジェネリクスを使うと...
func showInfo< T >(value: T) -> T {
return value
}
showInfo(50)
showInfo("Yamada")
showInfo(180.5)
//実行結果
50
Yamada
180.5
たとえば、異なる型の値を入れ替える処理も、型パラメータを使うことで一つの関数として表現可能です。
これにより、柔軟性と型安全性を両立でき、コンパイル時にエラーを検出しやすくなります。ジェネリクスを適切に設計することで、拡張しやすく保守性の高いSwiftコードを実現できるようになります。
エラーハンドリングの応用:throwsの実践パターン
Swiftのエラーハンドリングでは、throwsとResult型を状況に応じて使い分けることが重要です。throwsは関数の失敗を呼び出し元に委ねる仕組みであり、do-catch構文によって直感的にエラー処理を記述できるため、同期的でシンプルな処理に適しています。
以下がコード例です。
enum AgeError: Error{
case negativeAge
}
func showAge(_ a: Int) throws -> Int{
if a < 0{
throw AgeError.negativeAge
}
return a
}
do {
let result = try showAge(10)
print(result)
} catch {
print("エラー:", error)
}
コードの説明
エラーの種類を定義します。
今回の場合は年齢を表示したい場合であるのにも関わらず負の値が入力された場合のエラーを定義します。
次にshowAgeというのは年齢を表示する関数です。
「throws」を記述することでエラーが発生したときに先ほど定義したエラーを利用することができます。
また「_ a」というのはラベルなしでこの関数を使うときにラベルなしで値を入力できるということです。
doとcatchについてです。構造を詳しくみてみましょう。
do{
let result = try showAge(10)
print(result)
} catch {
print("エラー:", error)
}
doで関数を実行し、失敗した場合にエラーをcatchするという構造になっています。
また「let result」で「showAge(10)」の実行結果を代入する必要があります。
また「try」を関数の手前に記述する必要があります。
「catch」部分では「print("エラー:", error)」と記述することで先ほど定義したエラーの内容を表示することができます。
まとめ
コードの書き方を工夫することで効率よく開発を進めることを可能にします。
「throws」を用いることでエラーにも対応することでより本格的なアプリの開発を可能とします。
記述ミスでコードがうまくいかないということはよくあることなので、サンプルコードを試す場合でもし動かなかった場合、記述ミスをまず確認してみてください。
これからも開発ライフを応援しております。
関連記事
プロフィール
Yama
大阪出身の20代エンジニア。
Webサイトおよびモバイルアプリ開発を中心に学習・開発を行っています。
HTML、CSS、JavaScript、Python、Swift、Kotlinなどを
用いた開発に取り組んでいます。
2026/03/20