Skip to content

Commit 06a0f1b

Browse files
authored
Merge pull request #624 from stzn/copyable
[Concurrency, Generics, Protocols, Declarations]暗黙のプロトコル準拠、~Copyableなどの記述追加
2 parents 24e7115 + 0c9e50b commit 06a0f1b

File tree

4 files changed

+95
-14
lines changed

4 files changed

+95
-14
lines changed

language-guide/concurrency.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -421,17 +421,12 @@ struct TemperatureReading {
421421
}
422422
```
423423

424-
明示的に型を `Sendable` とマークし、`Sendable` プロトコルへ暗黙に準拠することを上書きするには、extension を使用します:
424+
`Sendable` プロトコルへの暗黙の準拠を上書きするには、`~Sendable` と書きます:
425425

426426
```swift
427-
struct FileDescriptor {
428-
let rawValue: CInt
427+
struct FileDescriptor: ~Sendable {
428+
let rawValue: Int
429429
}
430-
431-
@available(*, unavailable)
432-
extension FileDescriptor: Sendable { }
433430
```
434431

435-
上のコードは、POSIX ファイル記述子のラッパーの一部を示しています。ファイル記述子のインタフェースは、整数を使用して開いているファイルを識別して対話し、整数値は `Sendable` ですが、ファイル記述子は並行処理のドメイン間で送信することは安全ではありません。
436-
437-
上記のコードでは、`FileDescriptor` は暗黙的に `Sendable` に準拠できる基準を満たす構造体です。しかし、extension で `Sendable` への準拠を利用できなくし、この型が `Sendable` に準拠することを防いでいます。
432+
プロトコルへの暗黙の準拠を抑制する詳細な情報は、[暗黙の制約\(Implicit Constraints\)](./generics.md#暗黙の制約implicit-constraints) を参照ください。

language-guide/generics.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ジェネリクス\(Generics\)
22

3-
最終更新日: 2025/3/29
3+
最終更新日: 2025/5/24
44
原文: https://docs.swift.org/swift-book/LanguageGuide/Generics.html
55

66
複数の型で機能するコードを記述し、それらの型で準拠が必要な要件を指定する。
@@ -741,3 +741,34 @@ extension Container {
741741
* ジェネリック `where` 句では、シーケンスのイテレータが `Int` 型の要素を繰り返し処理することを要求します。これにより、シーケンス内のインデックスは、コンテナに使用されるインデックスと同じ型だということが保証されます
742742

743743
まとめると、これらの制約は、`indices` パラメータに渡される値が整数のシーケンスだということを意味します。
744+
745+
## <a id="implicit-constraints">暗黙の制約\(Implicit Constraints\)</a>
746+
747+
明示的に記述する制約に加えて、ジェネリックコードの多くの箇所で [`Copyable`](https://developer.apple.com/documentation/swift/copyable) のような非常に一般的なプロトコルへの準拠が暗黙的に要求されます。
748+
749+
このように記述する必要のないジェネリック制約は、*暗黙的な制約*として知られています。例えば、以下の両方の関数宣言は `MyType` がコピー可能であることを要求します。
750+
751+
```swift
752+
function someFunction<MyType> { ... }
753+
function someFunction<MyType: Copyable> { ... }
754+
```
755+
756+
上記のコードにおける `someFunction()` の両方の宣言は、ジェネリック型パラメータ `MyType` がコピー可能であることを要求します。最初のバージョンでは制約は暗黙的であり、2 番目のバージョンでは明示的に記述されています。ほとんどのコードでは、型はこれらの共通プロトコルに暗黙的に準拠します。詳細については、[プロトコルへの暗黙の準拠\(Implicit Conformance to a Protocol\)](./protocols.md#プロトコルへの暗黙の準拠implicit-conformance-to-a-protocol) を参照してください。
757+
758+
Swift のほとんどの型はこれらのプロトコルに準拠しているため、それらをほぼすべての場所に記述するのは冗長になります。代わりに、例外のみをマークすることで、共通の制約を省略する箇所を明示します。暗黙的な制約を抑制するには、プロトコル名の前にチルダ(`~`)を記述します。`~Copyable` は「コピー可能かもしれない」と読むことができ、この抑制された制約により、この位置でコピー可能な型とコピー不可能な型の両方が許可されます。`~Copyable` は型がコピー不可能であることを要求するものではないことに注意してください。たとえば、
759+
760+
```swift
761+
func f<MyType>(x: inout MyType) {
762+
let x1 = x // x1 の値は x の値のコピーです。
763+
let x2 = x // x2 の値は x の値のコピーです。
764+
}
765+
766+
func g<AnotherType: ~Copyable>(y: inout AnotherType) {
767+
let y1 = y // 代入によって y の値が consume されます。
768+
let y2 = y // エラー: 値が複数回 consume されました。
769+
}
770+
```
771+
772+
上記のコードでは、関数 `f()``MyType` がコピー可能であることを暗黙的に要求します。関数本体内では、代入において `x` の値が `x1``x2` にコピーされます。対照的に、`g()``AnotherType` に対する暗黙的な制約を抑制し、これによりコピー可能な値またはコピー不可能な値のいずれかを渡すことができます。関数本体内では、`AnotherType` がコピー不可能である可能性があるため、`y` の値をコピーすることはできません。代入は `y` の値を consume し、その値を複数回 consume するとエラーになります。`y` のようなコピー不可能な値は、in-out、 borrow、consume パラメータとして渡す必要があります。詳細については、[Borrowing と Consuming パラメータ\(Borrowing and Consuming Parameters\)](../language-reference/declarations.md#borrowing-and-consuming-parameters)を参照してください。
773+
774+
ジェネリックコードが特定のプロトコルへの暗黙的な制約をいつ含むかについての詳細は、そのプロトコルのリファレンスを参照してください。

language-guide/protocols.md

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# プロトコル\(Protocols\)
22

3-
最終更新日: 2024/3/18
3+
最終更新日: 2025/5/24
44
原文: https://docs.swift.org/swift-book/LanguageGuide/Protocols.html
55

66
準拠型が実装する必要がある要件を定義する。
@@ -248,6 +248,32 @@ class SomeSubClass: SomeSuperClass, SomeProtocol {
248248

249249
失敗可能イニシャライザ要件は、準拠する型の失敗可能または失敗しないイニシャライザによって満たされます。失敗しないイニシャライザ要件は、失敗しないイニシャライザまたは暗黙的にアンラップされた失敗可能イニシャライザによって満たされます。
250250

251+
## セマンティック要件のみを持つプロトコル\(Protocols that Have Only Semantic Requirements\)
252+
253+
上記のすべてのプロトコル例では、いくつかのメソッドやプロパティが必要ですが、プロトコル宣言に要件を含める必要はありません。プロトコルを使用して、セマンティック要件、つまりそれらの型の値がどのように動作するか、およびそれらがサポートする操作に関する要件を記述することもできます。
254+
255+
Swift 標準ライブラリは、必須のメソッドやプロパティを持たないいくつかのプロトコルを定義しています。
256+
257+
- [`Sendable`](https://developer.apple.com/documentation/swift/sendable): 並行処理ドメイン間で共有できる値用([`Sendable`\(Sendable Types\)](concurrency.md#sendable-型sendable-types)で説明)
258+
- [`Copyable`](https://developer.apple.com/documentation/swift/copyable): 関数に渡すときに Swift がコピーできる値用([Borrowing と Consuming パラメータ\(Borrowing and Consuming Parameters\)](../language-reference/declarations.md#borrowing-と-consuming-パラメータborrowing-and-consuming-parameters)で説明)
259+
- [`BitwiseCopyable`](https://developer.apple.com/documentation/swift/bitwisecopyable):ビット単位でコピーできる値用
260+
261+
これらのプロトコルの要件に関する情報については、それぞれのドキュメントの概要を参照してください。
262+
263+
これらのプロトコルを採用する場合も、他のプロトコルを採用する場合と同じ構文を使用します。唯一の違いは、プロトコルの要件を実装するメソッドやプロパティの宣言を含めないことです。次に例を示します。
264+
265+
```swift
266+
struct MyStruct: Copyable {
267+
var counter = 12
268+
}
269+
270+
extension MyStruct: BitwiseCopyable { }
271+
```
272+
273+
上記のコードは新しい構造体を定義しています。`Copyable` にはセマンティック要件しかないため、構造体宣言にはプロトコルを採用するためのコードはありません。同様に、`BitwiseCopyable` にはセマンティック要件しかないため、そのプロトコルを採用する extension の本体は空です。
274+
275+
通常、これらのプロトコルへの準拠を記述する必要はありません。代わりに、[プロトコルへの暗黙の準拠\(Implicit Conformance to a Protocol\)](#プロトコルへの暗黙の準拠implicit-conformance-to-a-protocol)で説明されているように、Swift が暗黙的に準拠を追加します。
276+
251277
## <a id="protocols-as-types">型としてのプロトコル\(Protocols as Types\)</a>
252278

253279
プロトコルは、実際には機能を実装しません。
@@ -512,6 +538,35 @@ for level in levels.sorted() {
512538
// expert(stars: 5)
513539
```
514540

541+
## <a id="implicit-conformance-to-a-protocol">プロトコルへの暗黙の準拠\(Implicit Conformance to a Protocol\)</a>
542+
543+
一部のプロトコルは非常によく使われるため、ほとんどの場合、新しい型を宣言するたびにそれらを記述することになるでしょう。以下のプロトコルについては、プロトコルの要件を実装する型を定義すると、Swift が自動的に準拠を推論するため、自分で記述する必要はありません。
544+
545+
- [`Copyable`](https://developer.apple.com/documentation/swift/copyable)
546+
- [`Sendable`](https://developer.apple.com/documentation/swift/sendable)
547+
- [`BitwiseCopyable`](https://developer.apple.com/documentation/swift/bitwisecopyable)
548+
549+
明示的に準拠を記述することもできますが、それによってコードの動作が変わることはありません。暗黙的な準拠を抑制するには、準拠リストのプロトコル名の前にチルダ(`~`)を記述します。
550+
551+
```swift
552+
struct FileDescriptor: ~Sendable {
553+
let rawValue: Int
554+
}
555+
```
556+
557+
上記のコードは、POSIX ファイルディスクリプタのラッパーの一部を示しています。`FileDescriptor` 構造体は `Sendable` プロトコルのすべての要件を満たしており、通常はこれにより `Sendable` になります。しかし、`~Sendable` と記述することで、この暗黙的な準拠が抑制されます。ファイルディスクリプタは開いているファイルを識別し操作するために整数を使用し、整数値は `Sendable` ですが、これを非 `Sendable` にすることで、特定種類のバグを回避するのに役立ちます。
558+
559+
暗黙的な準拠を抑制するもう 1 つの方法は、利用不可としてマークした extension を使用することです。
560+
561+
```swift
562+
@available(*, unavailable)
563+
extension FileDescriptor Sendable { }
564+
```
565+
566+
前の例のように、コードのある場所で `~Sendable` と記述した場合でも、プログラムの他の場所のコードは `FileDescriptor` 型を拡張して `Sendable` 準拠を追加できます。対照的に、この例の `unavailable` extension は、`Sendable` への暗黙的な準拠を抑制し、さらにコードの他の場所にある extension がその型に `Sendable` 準拠を追加するのを防ぎます。
567+
568+
> 注:上記のプロトコルに加えて、分散(distributed)アクターは、暗黙的に [`Codable`](https://developer.apple.com/documentation/swift/codable) プロトコルに準拠します。
569+
515570
## プロトコル型のコレクション\(Collections of Protocol Types\)
516571

517572
プロトコルは、[Protocols as Types\(型としてのプロトコル\)](protocols.md#protocols-as-types)で説明されているように、配列や辞書などのコレクションに格納される型として使用できます。この例では、`TextRepresentable` の配列を作成します。

language-reference/declarations.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 宣言\(Declarations\)
22

3-
最終更新日: 2024/6/23
3+
最終更新日: 2025/5/24
44
原文: https://docs.swift.org/swift-book/ReferenceManual/Declarations.html
55

66
型、演算子、変数、およびその他の名前と構造を紹介する。
@@ -487,9 +487,9 @@ func multithreadedFunction(queue: DispatchQueue, x: inout Int) {
487487

488488
より多くの議論と in-out パラメータの例については、[In-Out Parameters\(In-Out パラメータ\)](../language-reference/functions#functions-in-out-parameters)を参照ください。
489489

490-
#### Borrowing と Consuming パラメータ
490+
#### <a id="borrowing-and-consuming-parameters">Borrowing と Consuming パラメータ\(Borrowing and Consuming Parameters\)</a>
491491

492-
デフォルトでは、Swift は、必要なときに値をコピーし、関数呼び出し全体でオブジェクトの寿命を自動的に管理するために、一連のルールを使用します。デフォルトのルールは、ほとんどのケースでオーバーヘッドを最小限に抑えるように設計されています。この場合、コピー操作を明示的にマークするには `copy` を使用します。
492+
デフォルトでは、Swift は、必要なときに値をコピーし、関数呼び出し全体でオブジェクトの寿命を自動的に管理するために、一連のルールを使用します。デフォルトのルールは、ほとんどのケースでオーバーヘッドを最小限に抑えるように設計されています。この場合、コピー操作を明示的にマークするには `copy` を使用します。また、コピー不可型の値は、borrow または consume として渡されなければなりません。
493493

494494
デフォルトのルールを使用するかどうかに関係なく、Swift はオブジェクトの寿命と所有権がすべてのケースで正しく管理されることを保証します。これらのパラメータ修飾子は、正しさではなく、特定の使用パターンの相対的な効率性だけに影響します。
495495

0 commit comments

Comments
 (0)