30496


リファレンスの読み方ですが、SequenceプロトコルのmakeIterator()メソッドは、  
「Instance Methods」で記述されていて、「Default
Implementations」側には記述されていません。つまり、Sequenceプロトコルを採用したクラスで、makeIterator()を使用する場合、実装が必要だと判断してしまいますが、実際は必要ありませんでした。

[code]

    struct Countdown: Sequence, IteratorProtocol {
        var count: Int
    
        mutating func next() -> Int? {
            if count == 0 {
                return nil
            } else {
                defer { count -= 1 }
                return count
           }
        }
    }
    
    var iter = Countdown(count:3).makeIterator()
    
    for i in iter{
        print(i)
    }
    
[/code]

この場合のリファレンスの解釈の仕方教えてください。

勉強中でリファレンスを見ているのですが、読み方難しい。  
また日本語はないのでしょうか。


CC BY-SA 3.0
2016-11-18T02:00:20.817
30489
2016-11-18T05:19:09.163
2016-11-18T04:21:30.193
5519
11148
question
swift swift2 swift3
リファレンスの読み方がわからない


> SequenceプロトコルのmakeIterator()メソッドは、  
>  「Instance Methods」で記述されていて、「Default
> Implementations」側には記述されていません。つまり、Sequenceプロトコルを採用したクラスで、makeIterator()を使用する場合、実装が必要

ここまでは合っています。なのでSwiftのリファレンスがどういう構造になっているかは理解されていると思いますよ。全般に英語の解説を読むのを苦手とされているだけではないかと思います。

>
> Sequenceプロトコルを採用したクラスで、makeIterator()を使用する場合、実装が必要だと判断してしまいますが、実際は必要ありませんでした。

では、まず疑問の部分を説明します。

> Conforming to the Sequence Protocol
>
> Making your own custom types conform to Sequence enables many useful
> operations, like for-in looping and the contains method, without much
> effort. To add Sequence conformance to your own custom type, add a
> makeIterator() method that returns an iterator.

リファレンスには上記のように書いてあります。

Sequenceプロトコルはfor-
inループやcontainsメソッドなどの便利な操作を提供します。カスタムタイプをSequenceプロトコルに準拠させるには`makeIterator()`メソッドを実装し、イテレータを返します。

とあるので、Sequenceプロトコルに準拠させるには`makeIterator()`メソッドを実装する必要があります。

ところがこの解説には続きがあって、

> Alternatively, if your type can act as its own iterator, implementing the
> requirements of the IteratorProtocol protocol and declaring conformance to
> both Sequence and IteratorProtocol are sufficient.
>
> Here’s a definition of a Countdown sequence that serves as its own iterator.
> The makeIterator() method is provided as a default implementation.

カスタムタイプ自身がIteratorProtocolプロトコルを実装していてイテレータになれる場合（かつSequenceでもある）は、さらに簡単で、`makeIterator()`はデフォルト実装により提供される、とあります。

これが`makeIterator()`を実装しなくて良い理由です。

あなたの引用したコードはそのSequenceとIteratorProtocolを両方に準拠する場合は`makeIterator()`の実装は不要という例のコードなので、`makeIterator()`は書かれていません。

実際に、このコードからIteratorProtocolを取り除くと、

[code]

    struct Countdown: Sequence {
        ...
    
[/code]

次のようにコンパイルエラーになります。`makeIterator()`が実装されてないため、Sequenceプロトコルに準拠できていない、というエラーです。

[code]

    Type 'Countdown' does not conform to protocol 'Sequence'
    
[/code]

ここまでの仕組みはリファレンスにすべて書いてあります。なので必要なことはがんばって英語の説明に慣れることだと思います。

余談ですが、SequenceとIteratorProtocolに準拠すると`makeIterator()`がデフォルト実装により提供される、ということは書いてありますが、実際にどういう仕組みでそうなるのかはおそらくリファレンスだけではわかりません。

次のようにSequence.swiftのコードを見ると、Sequenceのプロトコルエクステンションとして、SequenceかつIteratorProtocolの場合に`makeIterator()`が実装されているのが分かります。

[code]

    /// A default makeIterator() function for `IteratorProtocol` instances that
    /// are declared to conform to `Sequence`
    extension Sequence
      where Self.Iterator == Self, Self : IteratorProtocol {
      /// Returns an iterator over the elements of this sequence.
      public func makeIterator() -> Self {
        return self
      }
    }
    
[/code]

<https://github.com/apple/swift/blob/master/stdlib/public/core/Sequence.swift#L631-L637>


CC BY-SA 3.0
2016-11-18T04:43:14.370
30496
2016-11-18T05:19:09.163
2016-11-18T05:19:09.163
5519
5519
30489
answer