diff --git a/language-guide/generics.md b/language-guide/generics.md index 270d7b5c..78214319 100644 --- a/language-guide/generics.md +++ b/language-guide/generics.md @@ -1,6 +1,6 @@ # ジェネリクス\(Generics\) -最終更新日: 2023/10/28 +最終更新日: 2025/3/29 原文: https://docs.swift.org/swift-book/LanguageGuide/Generics.html 複数の型で機能するコードを記述し、それらの型で準拠が必要な要件を指定する。 @@ -110,8 +110,10 @@ swapTwoValues(&someString, &anotherString) ほとんどの場合、型パラメータには、`Dictionary` の `Key` と `Value`、`Array` の `Element` などのその型パラメータの意味を表す名前が付いています。ただし、型パラメータに意味がない場合、上記の `swapTwoValues(_:_:)` 関数の `T` など、`T`、`U`、`V` などの 1 文字の名前を付けるのが伝統的です。 +型パラメータには、`T` や `MyTypeParameter` など常に大文字のキャメルケース名を指定し、それらが値ではなく*型*のプレースホルダであることを示します。 + > NOTE -> 型パラメータには常に大文字のキャメルケース名\(`T` や `MyTypeParameter` など\)を指定して、それらが値ではなく型のプレースホルダであることを示します。 +> 型パラメータに名前を付ける必要がなく、ジェネリック型の制約が単純であれば、代わりに使用できる他の軽量なシンタックスがあります。詳しくは、[Opaque パラメータ型\(Opaque Parameter Types\)](./opaque-types.md#opaque-parameter-types)を参照してください。 ## ジェネリック型\(Generic Types\) diff --git a/language-guide/opaque-types.md b/language-guide/opaque-types.md index f22ab4ec..45b10d03 100644 --- a/language-guide/opaque-types.md +++ b/language-guide/opaque-types.md @@ -1,6 +1,6 @@ # Opaque 型とBox プロトコル型\(Opaque and Boxed Protocol Types\) -最終更新日: 2024/04/23 +最終更新日: 2025/3/29 原文: https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html 値の型に関する実装の詳細を隠す。 @@ -302,3 +302,33 @@ print(type(of: twelve)) `twelve` の型は `Int` だと推論されます。これは、型推論が Opaque 型でも機能することを示しています。`makeOpaqueContainer(item:)` の実装では、Opaque 型の基になる型は `[T]` です。この場合、`T` は `Int` のため、戻り値は整数の配列で、関連型 `Item` は `Int` だと推論されます。`Container` のサブスクリプトは `Item` を返します。これは、`twelve` の型も `Int` だと推論されることを意味します。 +## Opaque パラメータ型\(Opaque Parameter Types\) + +Opaque 型を返すために `some` を書くことに加えて、関数や `subscript`、イニシャライザのパラメータの型にも `some` を書くことができます。ただし、パラメータの型に `some` を書く場合、それは Opaque 型ではなく、ジェネリクスの短い構文にすぎません。たとえば、以下の 2 つの関数は等価です: + +```swift +func drawTwiceGeneric(_ shape: SomeShape) -> String { + let drawn = shape.draw() + return drawn + "\n" + drawn +} + +func drawTwiceSome(_ shape: some Shape) -> String { + let drawn = shape.draw() + return drawn + "\n" + drawn +} +``` + +`drawTwiceGeneric(_:)` 関数は `SomeShape` という名前のジェネリック型パラメータを宣言し、`SomeShape` が `Shape` プロトコルに準拠するように制約を設けています。一方で `drawTwiceSome(_:)` 関数は引数の型として `some Shape` を使っています。これは新しい無名のジェネリック型パラメータを作り、その型が `Shape` プロトコルに準拠するように制約を課しています。ジェネリック型に名前がないため、関数内の別の箇所からその型に言及することはできません。 + +複数のパラメータの型の前に `some` を書く場合、それぞれのジェネリック型は独立しています。たとえば: + +```swift +func combine(shape s1: some Shape, with s2: some Shape) -> String { + return s1.draw() + "\n" + s2.draw() +} + +combine(smallTriangle, trapezoid) +``` + +`combine(shape:with:)` 関数では、最初と 2 番目のパラメータの型はどちらも `Shape` プロトコルに準拠している必要がありますが、同じ型である必要はありません。`combine(shape:with:)` を呼び出すときには、ここでは三角形と台形のように、異なる 2 つの図形を渡せます。 +[Generics](./generics.md)の章で説明されている名前付きジェネリック型パラメータの構文とは異なり、この軽量な構文ではジェネリック `where` 句や同一型 (`==`) の制約を含めることはできません。さらに、とても複雑な制約に対してこの軽量な構文を使うと、コードが読みにくくなる場合があります。 \ No newline at end of file diff --git a/language-reference/types.md b/language-reference/types.md index 58258ba2..1fb7444f 100644 --- a/language-reference/types.md +++ b/language-reference/types.md @@ -1,6 +1,6 @@ # 型\(Types\) -最終更新日: 2025/2/22 +最終更新日: 2025/3/29 原文: https://docs.swift.org/swift-book/ReferenceManual/Types.html 組み込みの名前付き型と複合型を使用します。 @@ -356,7 +356,7 @@ typealias PQR = PQ & Q & R _Opaque 型_は、基となる具体的な型を特定することなく、プロトコルまたはプロトコル合成に準拠する型を定義します。 -Opaque 型は、関数または `subscript` の戻り値の型、またはプロパティの型として使用できます。Opaque 型は、タプル型の一部や、配列の要素やオプショナルの `Wrapped` の型などのジェネリックな型には使用できません。 +Opaque 型は、関数または `subscript` の戻り値の型、関数・`subscript`・イニシャライザのパラメータの型、あるいはプロパティの型として使用できます。一方で、タプル型や、配列の要素やオプショナルの `Wrapped` 型などのジェネリック型の一部としては使用できません。 Opaque 型の形式は次のとおりです: @@ -372,6 +372,27 @@ _constraint_ に入るのは、クラス型、プロトコル型、プロトコ 戻り値の型として Opaque 型を使用する関数は、単一の型の値を返す必要があります。戻り値の型には、関数のジェネリックな型パラメータの一部を含めることができます。例えば、`someFunction()` は `T` 型または `Dictionary` 型の値を返すことができます。 +パラメータに Opaque 型を記述することは、ジェネリック型パラメータの名前を指定せずにジェネリック型を使用するための糖衣構文です。暗黙的なジェネリック型パラメータには、Opaque 型で指定されたプロトコルに準拠することを要求する制約が課されます。複数の Opaque 型を記述すると、それぞれが独自のジェネリック型パラメータを生成します。 + +たとえば、以下の宣言は等価です: + +```swift +func someFunction(x: some MyProtocol, y: some MyProtocol) { } +func someFunction(x: T1, y: T2) { } +``` + +2 つ目の宣言では、ジェネリック型パラメータ `T1` と `T2` には名前があるため、コードの他の場所でもこれらの型を参照できます。これに対して、1 つ目の宣言のジェネリック型パラメータには名前がないため、他のコードでは参照できません。 + +可変長パラメータの型として Opaque 型を使用することはできません。 + +戻り値として返される関数型のパラメータ、あるいはパラメータ型が関数型の場合に、そのパラメータとして Opaque 型を使用することもできません。こういった位置で Opaque 型を使うと、関数の呼び出し元が未知の型の値を構築しなければならなくなるためです。 + +```swift +protocol MyProtocol { } +func badFunction() -> (some MyProtocol) -> Void { } // エラー +func anotherBadFunction(callback: (some MyProtocol) -> Void) { } // エラー +``` + > Grammar of an opaque type: > > *opaque-type* → **`some`** *type*