見出し画像

「解いて学ぶ」Swift入門

はじめに

何となくわかった気になったけれど、実はわかってない、ということがよくあります。そこで、「解いて学ぶ」シリーズでは、問題を解いてアウトプットしながら学ぶことで深く理解していきます。今回は、プログラミング言語Swiftです。

1. 問題編

解答は、最後の「6. 問題編の解答と解説」にあります。

初級

  1. Swiftで定数を宣言するキーワードは何ですか?

  2. Swiftの整数型のデータ型は何ですか?

  3. 配列を作成するために使用する記号は何ですか?

  4. 辞書を作成するために使用する記号は何ですか?

  5. Swiftで繰り返し処理を行うための2つの方法は何ですか?

  6. 関数を定義するためのキーワードは何ですか?

  7. オプショナルを宣言するために使用する記号は何ですか?

  8. クロージャとは何ですか?

  9. 構造体を定義するためのキーワードは何ですか?

  10. プロトコルを定義するためのキーワードは何ですか?

中級

  1. 変数と定数の違いは何ですか?

  2. Swiftで小数を扱うための2つのデータ型は何ですか?

  3. 配列の要素にアクセスする方法は何ですか?

  4. 辞書から値を取得する方法は何ですか?

  5. if文の条件式に使用できるデータ型は何ですか?

  6. 関数の引数にデフォルト値を設定する方法は何ですか?

  7. オプショナルの値を取り出す方法は何ですか?

  8. クロージャの簡略化の方法は何ですか?

  9. 構造体とクラスの主な違いは何ですか?

  10. クラスや構造体がプロトコルに準拠する方法は何ですか?

上級

  1. 型推論が効かない場合、どのように型を明示的に指定できますか?

  2. 文字列を結合する方法は何ですか?

  3. 配列の要素を安全にアクセスする方法は何ですか?

  4. 辞書の値を安全に取得する方法は何ですか?

  5. switch文で条件にマッチしない場合に実行するコードを記述するにはどうすればよいですか?

  6. 関数の戻り値の型を指定する方法は何ですか?

  7. オプショナルチェイニングとは何ですか?

  8. クロージャがキャプチャするとは何ですか?

  9. クラスにはあるが、構造体にはない機能は何ですか?

  10. プロトコルのデフォルト実装を提供する方法は何ですか?

2. Swiftの基礎

2.1. Swiftとは?

  • Apple が開発したiOS、macOS、watchOSといったAppleプラットフォーム向けのアプリケーションを開発するためのプログラミング言語です。

  • 安全性、速度、モダンな機能を提供します。

  • シンプルでわかりやすい構文を持っています。

2.2. Swiftの特徴

  • 安全性

    • Swiftは、型安全(type safety)を重視して設計されており、コンパイル時に多くのエラーが検出されることで、実行時のエラーを最小限に抑えます。また、オプショナル型(Optional type)を利用することで、nil(null)参照の問題も効果的に管理できます。

  • 速度

    • Swiftは高速な実行性能を持っており、多くの場合、Objective-CやPythonといった他の言語と比較しても優れたパフォーマンスが得られます。

  • モダンな機能

    • Swiftは関数型プログラミングやプロトコル指向プログラミングなどの現代的なプログラミングパラダイムをサポートしています。また、ジェネリクスやクロージャ、パターンマッチングなどの高度な機能も提供しています。

  • シンプルで読みやすい構文

    • Swiftはシンプルで直感的な構文を持っており、読みやすく、学びやすい言語です。また、C言語のようなセミコロンが省略可能であることや、インデントを用いたコードブロックの表現など、簡潔なコードが書ける点も特徴です。

  • プラットフォームの互換性

    • Swiftは主にAppleのエコシステムで使用されていますが、オープンソースであるため、LinuxやWindowsなどの他のプラットフォームでも利用可能です。

  • Playgrounds

    • Xcode(Appleの統合開発環境)の機能の1つであるPlaygroundsを利用することで、Swiftコードをインタラクティブに実行し、結果をすぐに確認できる環境が提供されます。これにより、学習やプロトタイピングが効率的に行えます。

  • 継続的な進化

  • SwiftはAppleと開発者コミュニティによって継続的に開発・改善されており、新しい機能や最適化が定期的に追加されています。

3. Swiftの基本的な機能10

3.1.変数と定数:

変数はvarキーワードを使用し、定数はletキーワードを使用します。

var variable = "This is a variable"
let constant = "This is a constant"

3.2. 型アノテーション:

型アノテーションを使用して、変数や定数の型を明示的に指定できます。

var integer: Int = 42
let string: String = "Hello, World!"

3.3. 条件文:

if文を使用して条件を判断し、処理を分岐させることができます。

let number = 10
if number > 5 {
    print("The number is greater than 5")
} else {
    print("The number is not greater than 5")
}

3.4. 繰り返し:

for-inループを使用して、コレクションや範囲を繰り返し処理できます。

for i in 1...5 {
    print("Iteration: \(i)")
}

3.5. 関数:

funcキーワードを使用して、関数を定義できます。

func greet(name: String) {
    print("Hello, \(name)!")
}
greet(name: "John")

3.6. オプショナル型:

オプショナル型を使用して、値が存在しない可能性を示すことができます。

var optionalString: String? = "Hello"
optionalString = nil // 値が存在しないことを示す

3.7. オプショナルバインディング:

if letやguard letを使用して、オプショナル型の値を安全にアンラップできます。

if let unwrappedString = optionalString {
    print("The string is not nil: \(unwrappedString)")
} else {
    print("The string is nil")
}

3.8. クラス:

classキーワードを使用して、クラスを定義できます。

class Dog {
    var name: String

    init(name: String) {
        self.name = name
    }

    func bark() {
        print("Woof, woof!")
    }
}
let dog = Dog(name: "Buddy")
dog.bark()

3.9. 構造体:

structキーワードを使用して、構造体を定義できます。

struct Point {
    var x: Double
    var y: Double
}
let point = Point(x: 3.0, y: 4.0)

3.10. クロージャ:

無名関数として、クロージャを定義できます。

let add: (Int, Int) -> Int = { (a, b) in
    return a + b
}
let result = add(1, 2) // 3

4. Swiftの高度な機能10

4.1. プロトコル:

プロトコルは、特定のメソッドやプロパティの要件を定義します。クラス、構造体、列挙型はプロトコルに準拠して、これらの要件を実装できます。

protocol Drawable {
    func draw()
}

class Circle: Drawable {
    func draw() {
        print("Drawing a circle")
    }
}

4.2. ジェネリクス:

ジェネリクスは、型に依存しないコードを記述できる機能です。これにより、再利用性が高く柔軟なコードが書けます。

func swapValues<T>(a: inout T, b: inout T) {
    let temp = a
    a = b
    b = temp
}

var num1 = 1
var num2 = 2
swapValues(a: &num1, b: &num2)

4.3. 列挙型:

列挙型(enum)は、関連する値のグループを定義し、状態やオプションの管理に役立ちます。

enum TrafficLight {
    case red, yellow, green
}

let light = TrafficLight.red

4.4. エラーハンドリング:

throwsキーワードを使用してエラーをスローする関数を定義し、do-catch構文でエラーを捕捉・処理できます。

enum FileError: Error {
    case notFound
}

func readFile(name: String) throws {
    throw FileError.notFound
}

do {
    try readFile(name: "file.txt")
} catch FileError.notFound {
    print("File not found")
}

4.5. 型エイリアス:

typealiasキーワードを使用して、既存の型に別名を付けることができます。

typealias Integer = Int

let number: Integer = 42

4.6. サブスクリプト:

サブスクリプトを使用して、コレクションやリストの要素に簡単にアクセスできるインターフェースを定義します。

struct Vector {
    var x: Double, y: Double

    subscript(index: Int) -> Double {
        get {
            return index == 0 ? x : y
        }
        set {
            if index == 0 {
                x = newValue
            } else {
                y = newValue
            }
        }
    }
}

var vector = Vector(x: 3.0, y: 4.0)
vector[0] = 5.0

4.7. プロパティオブザーバー:

willSetとdidSetプロパティオブザーバーを使用して、プロパティの値が変更されたときに実行されるコードを定義できます。これにより、プロパティの値の変更に応じて追加の処理を行うことができます。

class Counter {
    var count = 0 {
        didSet {
            print("Count changed from \(oldValue) to \(count)")
        }
    }
}

let counter = Counter()
counter.count = 1 // "Count changed from 0 to 1"と出力される

4.8. イニシャライザのデリゲーション:

イニシャライザが他のイニシャライザを呼び出すことで、コードの重複を避けて初期化処理を共有できます。クラスではconvenienceイニシャライザがデリゲーションを行い、構造体ではイニシャライザが自動的にデリゲーションできます。

class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    convenience init() {
        self.init(name: "Unknown", age: 0)
    }
}

let person = Person()

4.9. 拡張:

extensionキーワードを使用して、既存の型に新しい機能を追加できます。これにより、型の定義を変更せずに機能を追加することができます。

extension Int {
    func squared() -> Int {
        return self * self
    }
}

let number = 3
print(number.squared()) // 9と出力される

4.10. ネストした型:

クラス、構造体、列挙型は、ネストした型を定義できます。これにより、関連する型をまとめて管理できます。

struct Matrix {
    struct Size {
        var rows: Int, columns: Int
    }

    var size: Size
}

let matrixSize = Matrix.Size(rows: 3, columns: 3)
let matrix = Matrix(size: matrixSize)

5. 解説を読む前の解説

5.1.定数と変数

let constantValue = 10 
var variableValue = 20 
variableValue = 30

この例では、letキーワードを使ってconstantValueという名前の定数を宣言し、10という値を代入しています。定数は一度代入されると値を変更できません。次に、varキーワードを使ってvariableValueという名前の変数を宣言し、20という値を代入しています。変数は値を変更できるため、variableValueに30という新しい値を代入しています。

5.2. 基本的なデータ型

let intExample: Int = 42 
let doubleExample: Double = 3.14 
let boolExample: Bool = true 
let stringExample: String = "Hello, World!"

この例では、Swiftの基本的なデータ型を宣言しています。Int型のintExampleに42を、Double型のdoubleExampleに3.14を、Bool型のboolExampleにtrueを、そしてString型のstringExampleに"Hello, World!"をそれぞれ代入しています。

5.3. 制御構造

if boolExample {
    print("The condition is true.")
} else {
    print("The condition is false.") 
} 

for i in 1...5 {
    print("Loop iteration \(i)") 
}

この例では、制御構造のif文とforループを示しています。boolExampleがtrueの場合、"The condition is true."と表示され、falseの場合、"The condition is false."と表示されます。次に、forループを使用して1から5までの整数に対して繰り返し処理を行い、"Loop iteration"に続いて各整数を表示しています。

5.4. 関数

func greet(name: String) {
    print("Hello, \(name)!") 
} 

greet(name: "Alice") 

この例では、greetという関数を定義しています。この関数は、String型のnameパラメータを受け取り、"Hello, "に続いて名前を表示します。関数の呼び出しでは、greet(name: "Alice")と記述して、引数に"Alice"を渡しています。

5.5. オプショナル

var optionalInt: Int? = nil 
optionalInt = 42 

if let unwrappedInt = optionalInt {
    print("The value is \(unwrappedInt)")
} else {
    print("The value is nil") 
} 

この例では、Int型のオプショナル変数optionalIntを宣言し、最初にnilを代入しています。次に、`optional var optionalInt: Int? = nil optionalInt = 42 if let unwrappedInt = optionalInt { print("The value is \(unwrappedInt)") } else { print("The value is nil") }
次に、optionalIntに42を代入しています。if let構文を使用してオプショナルの値をアンラップしています。optionalIntがnilでない場合、アンラップされた値がunwrappedIntに格納され、"The value is (unwrappedInt)"が表示されます。optionalIntがnilの場合、"The value is nil"が表示されます。

5.6. クロージャ

let numbers = [1, 2, 3, 4, 5] 
let squaredNumbers = numbers.map { $0 * $0 } 
print(squaredNumbers) // [1, 4, 9, 16, 25]

この例では、numbersという整数の配列を宣言し、map関数を使用して各要素を2乗した新しい配列squareNumbersを作成しています。クロージャは{ $0 * $0 }で表現され、$0はクロージャの最初の引数(配列の各要素)を表しています。print(squaredNumbers)で、2乗された値の配列が表示されます。

5.7. 構造体とクラス

struct Point {
    var x: Double
    var y: Double 
} 

class Circle {
    var center: Point
    var radius: Double

    init(center: Point, radius: Double) {
        self.center = center
        self.radius = radius
    } 
}

この例では、Pointという構造体とCircleというクラスを定義しています。Point構造体はxとyというDouble型のプロパティを持っています。CircleクラスはcenterというPoint型のプロパティとradiusというDouble型のプロパティを持っており、initメソッドで初期化されます。

5.8. プロトコル

protocol Drawable {
    func draw() 
} 

class Rectangle: Drawable {
    func draw() {
        print("Drawing a rectangle")
    } 
} 

let drawable: Drawable = Rectangle() 
drawable.draw()

この例では、Drawableというプロトコルを定義しています。このプロトコルは、drawというメソッドを持つことを要求しています。Rectangleクラスは、Drawableプロトコルに準拠してdrawメソッドを実装しています。let drawable: Drawable = Rectangle()で、Drawable型のdrawable定数にRectangleインスタンスを代入し、drawable.draw() protocol Drawable { func draw() } class Rectangle: Drawable { func draw() { print("Drawing a rectangle") } } let drawable: Drawable = Rectangle() drawable.draw()
で、Drawable型のdrawable定数にRectangleインスタンスを代入し、drawable.draw()でdrawメソッドが呼び出され、"Drawing a rectangle"が表示されます。

5.9. エクステンション

extension Int {
    var isEven: Bool {
        return self % 2 == 0
    } 
} 

print(4.isEven) // true

この例では、Int型にisEvenというプロパティを追加するエクステンションを定義しています。このプロパティは、整数が偶数であるかどうかを判断し、真偽値を返します。print(4.isEven)で、4が偶数であるため、trueが表示されます。

5.10. エラーハンドリング

enum CustomError: Error {
    case invalidInput 
} 

func processInput(_ input: Int) throws {
    if input < 0 {
        throw CustomError.invalidInput
    } 
} 

do {
    try processInput(-1)
    } catch {
    print("Caught an error: \(error)") 
}

この例では、エラーハンドリングを示しています。CustomErrorというエラー型を定義し、invalidInputというケースを持っています。processInput関数は、入力が負の場合にCustomError.invalidInputをスローします。do-catch構文を使用して、processInput関数を呼び出し、エラーを捕捉して処理します。この例では、-1を引数に渡しているため、"Caught an error: invalidInput"が表示されます。

6. 問題編の解答と解説

6.1. 変数と定数

  • 変数と定数

    • 初級: Swiftで定数を宣言するキーワードは何ですか?

      • 解答: let

      • 解説: Swiftでは、letキーワードを使用して定数を宣言します。定数は一度値が設定されると、その値を変更することはできません。

    • 中級: 変数と定数の違いは何ですか?

      • 解答: 変数は値を変更できますが、定数は値を変更できません。

      • 解説: Swiftでは、varキーワードで変数を宣言し、値を変更できます。一方、letキーワードで定数を宣言し、値が一度設定されると変更できません。

    • 上級: 型推論が効かない場合、どのように型を明示的に指定できますか?

      • 解答: 型をコロン(:)の後に記述することで、明示的に指定できます。

      • 解説: Swiftでは、通常型推論を利用して変数や定数の型を自動的に決定しますが、型推論が効かない場合や明示的に型を指定したい場合は、変数や定数の宣言時にコロン(:)の後に型を記述します。例: let intValue: Int = 5

6.2. 基本データ型

  • 基本データ型

    • 初級: Swiftの整数型のデータ型は何ですか?

      • 解答: Int

      • 解説: Swiftの整数型のデータ型はIntです。Intはプラットフォームによってサイズが異なり、32ビットプラットフォームではInt32、64ビットプラットフォームではInt64と同じサイズになります。

      • 中級: Swiftで小数を扱うための2つのデータ型は何ですか?

        • 解答: FloatDouble

        • 解説: Swiftでは、小数を扱うためにFloatDoubleの2つのデータ型があります。Floatは32ビット浮動小数点数、Doubleは64ビット浮動小数点数を表します。通常、精度が必要な場合はDoubleを使用します。

      • 上級: 文字列を結合する方法は何ですか?

        • 解答: +演算子、または文字列補間を使用します。

        • 解説: Swiftでは、2つの文字列を結合するために+演算子を使用することができます。例: let message = "Hello, " + "World!"。また、文字列補間を使って変数や定数の値を文字列に埋め込むこともできます。例: let name = "John"; let greeting = "Hello, \(name)!"

6.3. 配列

  • 配列

    • 初級: 配列を作成するために使用する記号は何ですか?

      • 解答: 角括弧[]

      • 解説: Swiftでは、角括弧[]を使用して配列を作成します。例: let numbers = [1, 2, 3]

    • 中級: 配列の要素にアクセスする方法は何ですか?

      • 解答: インデックスを使用します。

      • 解説: Swiftでは、配列の要素にアクセスするためにインデックスを使用します。インデックスは0から始まります。例: let firstNumber = numbers[0]

    • 上級: 配列の要素を安全にアクセスする方法は何ですか?

      • 解答: indicesプロパティとcontains(_:)メソッドを使用します。

      • 解説: Swiftでは、配列の範囲外のインデックスにアクセスするとランタイムエラーが発生します。これを回避するために、indicesプロパティとcontains(_:)メソッドを使用して、インデックスが配列の範囲内にあることを確認できます。例: if numbers.indices.contains(index) { let value = numbers[index] }

6.4. 辞書

  • 辞書

    • 初級: 辞書を作成するために使用する記号は何ですか?

      • 解答: 角括弧[]とコロン:

      • 解説: Swiftでは、角括弧[]を使用して辞書を作成し、キーと値のペアをコロン:で区切ります。例: let ages = ["John": 30, "Jane": 28]

    • 中級: 辞書から値を取得する方法は何ですか?

      • 解答: キーを使用します。

      • 解説: Swiftでは、辞書から値を取得するためにキーを使用します。ただし、キーが存在しない場合、nilが返されます。例: let age = ages["John"]

    • 上級: 辞書の値を安全に取得する方法は何ですか?

      • 解答: キーが存在するかどうかを確認し、オプショナルバインディングを使用します。

      • 解説: Swiftでは、辞書のキーが存在しない場合、nilが返されます。値を安全に取得するために、キーが存在するかどうかを確認し、オプショナルバインディングを使用して値を取り出すことができます。例: if let age = ages["John"] { print("John's age is \(age)") } else { print("John's age is not found") }

6.5. 制御構造

  • 制御構造

    • 初級: Swiftで繰り返し処理を行うための2つの方法は何ですか?

      • 解答: for-inループとwhileループ

      • 解説: Swiftでは、繰り返し処理を行うためにfor-inループとwhileループを使用できます。for-inループは、コレクションや範囲に対して繰り返し処理を行います。whileループは、条件が真である間、繰り返し処理を行います。

    • 中級: if文の条件式に使用できるデータ型は何ですか?

      • 解答: Bool

      • 解説: Swiftでは、if文の条件式にBool型の値を使用します。他のデータ型は暗黙的にBool型に変換されません。

    • 上級: switch文で条件にマッチしない場合に実行するコードを記述するにはどうすればよいですか?

      • 解答: defaultキーワードを使用します。

      • 解説: Swiftのswitch文では、すべての条件が網羅されている必要があります。条件にマッチしない場合に実行するコードを記述するために、defaultキーワードを使用します。例: switch value { case 1: print("One") default: print("Other") }

6.6. 関数

  • 関数

    • 初級: 関数を定義するためのキーワードは何ですか?

      • 解答: func

      • 解説: Swiftでは、funcキーワードを使用して関数を定義します。例: func sayHello() { print("Hello, world!") }

    • 中級: 関数の引数にデフォルト値を設定する方法は何ですか?

      • 解答: 引数の型の後に=とデフォルト値を記述します。

      • 解説: Swiftでは、関数の引数にデフォルト値を設定することができます。引数の型の後に=とデフォルト値を記述することで、関数呼び出し時にその引数を省略できます。例: func greet(name: String = "World") { print("Hello, \(name)!") }

    • 上級: 関数の戻り値の型を指定する方法は何ですか?

      • 解答: 関数名と引数リストの後に->と戻り値の型を記述します。

      • 解説: Swiftでは、関数の戻り値の型を指定するために、関数名と引数リストの後に->と戻り値の型を記述します。例: func add(a: Int, b: Int) -> Int { return a + b }

6.7. オプショナル

  • オプショナル

    • 初級: オプショナルを宣言するために使用する記号は何ですか?

      • 解答: 疑問符?

      • 解説: Swiftでは、オプショナルを宣言するために疑問符?を使用します。オプショナルは、値が存在しないことを許容する型です。例: var optionalString: String?

    • 中級: オプショナルの値を取り出す方法は何ですか?

      • 解答: オプショナルバインディングや強制アンラップを使用します。

      • 解説: Swiftでは、オプショナルの値を取り出すためにオプショナルバインディング(if letguard let)を使用するか、強制アンラップ(!)を使用します。ただし、強制アンラップは値がnilの場合にランタイムエラーが発生するため、使用には注意が必要です。

    • 上級: オプショナルチェイニングとは何ですか?

      • 解答: オプショナルチェイニングは、オプショナルのプロパティやメソッドにアクセスする際に、nilチェックを簡潔に記述するための機能です。

      • 解説: Swiftでは、オプショナルチェイニングを使用することで、オプショナルのプロパティやメソッドにアクセスする際のnilチェックを簡潔に記述できます。オプショナルチェイニングは、オプショナルの値がnilである場合に、その後のアクセスや処理をスキップし、nilを返します。オプショナルチェイニングは、オプショナルの後に疑問符?を使用して記述します。例: let count = optionalArray?.count

6.8. クロージャ

  • クロージャ

    • 初級: クロージャとは何ですか?

      • 解答: クロージャは、名前を持たない関数や、独立したコードブロックです。

      • 解説: Swiftのクロージャは、名前を持たない関数や独立したコードブロックで、変数や定数と同様に渡されたり、キャプチャされたりできます。クロージャは、関数と同様にパラメータと戻り値を持つことができます。

    • 中級: クロージャの簡略化の方法は何ですか?

      • 解答: 引数名の省略、戻り値の省略、キーワードinの省略など。

      • 解説: Swiftのクロージャは、引数名を省略して$0, $1などでアクセスできます。また、一行で完結する場合は、キーワードreturninを省略できます。さらに、型推論を利用して、引数型や戻り値型の省略もできます。

    • 上級: クロージャがキャプチャするとは何ですか?

      • 解答: クロージャがキャプチャするとは、クロージャ内で参照される外部の変数や定数の現在の値を保持することです。

      • 解説: Swiftのクロージャは、参照される外部の変数や定数を自動的にキャプチャします。これにより、クロージャが実行されるタイミングで、キャプチャされた変数や定数の現在の値が利用できます。

6.9. 構造体とクラス

  • 構造体とクラス

    • 初級: 構造体を定義するためのキーワードは何ですか?

      • 解答: struct

      • 解説: Swiftでは、structキーワードを使用して構造体を定義します。構造体は、複数のプロパティやメソッドを持つことができます。

    • 中級: 構造体とクラスの主な違いは何ですか?

      • 解答: 構造体は値型で、クラスは参照型です。

      • 解説: Swiftの構造体は値型で、変数や定数に代入されると新しいインスタンスが作成されます。クラスは参照型で、変数や定数に代入されると、インスタンスへの参照が共有されます。この違いにより、構造体は値が変更されると新しいインスタンスが生成されるため、元の値が影響を受けません。一方、クラスでは複数の参照が同じインスタンスを指すため、変更が他の参照に影響を与えることがあります。

    • 上級: クラスにはあるが、構造体にはない機能は何ですか?

      • 解答: 継承、デイニシャライザ、参照カウントなど。

      • 解説: Swiftのクラスには、継承(他のクラスから派生すること)、デイニシャライザ(インスタンスが破棄される前にクリーンアップを行うためのコード)、参照カウント(インスタンスがいくつの参照によって保持されているかを管理)などの機能がありますが、構造体にはこれらの機能はありません。

6.10. プロトコル

  • プロトコル

    • 初級: プロトコルを定義するためのキーワードは何ですか?

      • 解答: protocol

      • 解説: Swiftでは、protocolキーワードを使用してプロトコルを定義します。プロトコルは、特定のメソッドやプロパティを持つことを要求する仕様です。

    • 中級: クラスや構造体がプロトコルに準拠する方法は何ですか?

      • 解答: 型の定義にプロトコル名をコロンの後に記述します。

      • 解説: Swiftでは、クラスや構造体がプロトコルに準拠することを宣言するために、型の定義にプロトコル名をコロンの後に記述します。例: struct MyStruct: MyProtocol { ... }

    • 上級: プロトコルのデフォルト実装を提供する方法は何ですか?

      • 解答: エクステンションを使用してプロトコルに実装を追加します。

      • 解説: Swiftでは、エクステンションを使用してプロトコルにデフォルト実装を提供することができます。これにより、準拠する型がそのメソッドやプロパティの実装を省略できます。例: extension MyProtocol { func defaultMethod() { print("Default implementation") } }


この記事が気に入ったらサポートをしてみませんか?