Skip to content

Opaqueパラメータ型の説明追加 #615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions language-guide/generics.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ジェネリクス\(Generics\)

最終更新日: 2023/10/28
最終更新日: 2025/3/29
原文: https://docs.swift.org/swift-book/LanguageGuide/Generics.html

複数の型で機能するコードを記述し、それらの型で準拠が必要な要件を指定する。
Expand Down Expand Up @@ -110,8 +110,10 @@ swapTwoValues(&someString, &anotherString)

ほとんどの場合、型パラメータには、`Dictionary<Key, Value>` の `Key` と `Value`、`Array<Element>` の `Element` などのその型パラメータの意味を表す名前が付いています。ただし、型パラメータに意味がない場合、上記の `swapTwoValues(_:_:)` 関数の `T` など、`T`、`U`、`V` などの 1 文字の名前を付けるのが伝統的です。

型パラメータには、`T` や `MyTypeParameter` など常に大文字のキャメルケース名を指定し、それらが値ではなく*型*のプレースホルダであることを示します。

> NOTE
> 型パラメータには常に大文字のキャメルケース名\(`T` や `MyTypeParameter` など\)を指定して、それらが値ではなく型のプレースホルダであることを示します
> 型パラメータに名前を付ける必要がなく、ジェネリック型の制約が単純であれば、代わりに使用できる他の軽量なシンタックスがあります。詳しくは、[Opaque パラメータ型\(Opaque Parameter Types\)](./opaque-types.md#opaque-parameter-types)を参照してください

## <a id="generic-types">ジェネリック型\(Generic Types\)</a>

Expand Down
32 changes: 31 additions & 1 deletion language-guide/opaque-types.md
Original file line number Diff line number Diff line change
@@ -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

値の型に関する実装の詳細を隠す。
Expand Down Expand Up @@ -302,3 +302,33 @@ print(type(of: twelve))

`twelve` の型は `Int` だと推論されます。これは、型推論が Opaque 型でも機能することを示しています。`makeOpaqueContainer(item:)` の実装では、Opaque 型の基になる型は `[T]` です。この場合、`T` は `Int` のため、戻り値は整数の配列で、関連型 `Item` は `Int` だと推論されます。`Container` のサブスクリプトは `Item` を返します。これは、`twelve` の型も `Int` だと推論されることを意味します。

## <a id="generic-parameter-types">Opaque パラメータ型\(Opaque Parameter Types\)</a>

Opaque 型を返すために `some` を書くことに加えて、関数や `subscript`、イニシャライザのパラメータの型にも `some` を書くことができます。ただし、パラメータの型に `some` を書く場合、それは Opaque 型ではなく、ジェネリクスの短い構文にすぎません。たとえば、以下の 2 つの関数は等価です:

```swift
func drawTwiceGeneric<SomeShape: Shape>(_ 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` 句や同一型 (`==`) の制約を含めることはできません。さらに、とても複雑な制約に対してこの軽量な構文を使うと、コードが読みにくくなる場合があります。
25 changes: 23 additions & 2 deletions language-reference/types.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 型\(Types\)

最終更新日: 2025/2/22
最終更新日: 2025/3/29
原文: https://docs.swift.org/swift-book/ReferenceManual/Types.html

組み込みの名前付き型と複合型を使用します。
Expand Down Expand Up @@ -356,7 +356,7 @@ typealias PQR = PQ & Q & R

_Opaque 型_は、基となる具体的な型を特定することなく、プロトコルまたはプロトコル合成に準拠する型を定義します。

Opaque 型は、関数または `subscript` の戻り値の型、またはプロパティの型として使用できます。Opaque 型は、タプル型の一部や、配列の要素やオプショナルの `Wrapped` の型などのジェネリックな型には使用できません
Opaque 型は、関数または `subscript` の戻り値の型、関数・`subscript`・イニシャライザのパラメータの型、あるいはプロパティの型として使用できます。一方で、タプル型や、配列の要素やオプショナルの `Wrapped` 型などのジェネリック型の一部としては使用できません

Opaque 型の形式は次のとおりです:

Expand All @@ -372,6 +372,27 @@ _constraint_ に入るのは、クラス型、プロトコル型、プロトコ

戻り値の型として Opaque 型を使用する関数は、単一の型の値を返す必要があります。戻り値の型には、関数のジェネリックな型パラメータの一部を含めることができます。例えば、`someFunction<T>()` は `T` 型または `Dictionary<String, T>` 型の値を返すことができます。

パラメータに Opaque 型を記述することは、ジェネリック型パラメータの名前を指定せずにジェネリック型を使用するための糖衣構文です。暗黙的なジェネリック型パラメータには、Opaque 型で指定されたプロトコルに準拠することを要求する制約が課されます。複数の Opaque 型を記述すると、それぞれが独自のジェネリック型パラメータを生成します。

たとえば、以下の宣言は等価です:

```swift
func someFunction(x: some MyProtocol, y: some MyProtocol) { }
func someFunction<T1: MyProtocol, T2: MyProtocol>(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*
Expand Down