简体   繁体   English

协议符合

[英]Protocol conforming

I am experimenting some swift features.( Collection protocols). 我正在尝试一些快速的功能。(收集协议)。 I would like to implement a structure that implements CollectionType. 我想实现一个实现CollectionType的结构。 My code : 我的代码:

 struct Book {
    let id : String
    let name : String

    init(id: String, name: String) {
        self.id = id
        self.name = name
    }
}
struct BookCollection {
    var books : [Book]
}

First attempt : 第一次尝试 :

extension BookCollection : CollectionType {
}

Compiler error : "Type BookCollection does not conform to the protocol Indexable" 编译器错误:“类型BookCollection不符合协议Indexable”

Ok compiler let's conform to Indexable : 好的编译器让我们符合Indexable:

extension BookCollection : CollectionType {
    var startIndex: Int {return 0}
    var endIndex: Int {return books.count}

    subscript(idx: Int) -> Book {
        return books[idx]
    }
}

The code is working now. 代码现在正在运行。

My Question is : if we forget the compiler errors, is there an easy way to know what functions/properties we should implement when conforming to a protocol in swift ? 我的问题是:如果我们忘记编译器错误,是否有一种简单的方法可以知道在符合swift协议时我们应该实现哪些功能/属性? Thanks 谢谢

PS : I don't want to read all the extensions to see if there are a default implementation or no, it's painful PS:我不想阅读所有扩展以查看是否存在默认实现,这是非常痛苦的

The compiler errors will tell you. 编译器错误会告诉你。 I put your code in a playground and saw the following errors 我把你的代码放在游乐场,看到以下错误

Playground execution failed: MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'Indexable'
extension BookCollection: CollectionType
^
Swift.Indexable:6:15: note: unable to infer associated type 'Index' for protocol 'Indexable'
    typealias Index : ForwardIndexType
              ^
Swift.CollectionType:2:12: note: inferred type 'Range<BookCollection.Index>' (by matching requirement 'subscript') is invalid: does not conform to 'ForwardIndexType'
   public subscript (bounds: Range<Self.Index>) -> Slice<Self> { get }
           ^
MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'SequenceType'
extension BookCollection: CollectionType
^
Swift.SequenceType:35:17: note: protocol requires function 'generate()' with type '() -> Generator'
    public func generate() -> Self.Generator
                ^
Swift.SequenceType:2:17: note: candidate has non-matching type '<`Self`> () -> `Self`' (aka '<τ_0_0> () -> τ_0_0')
    public func generate() -> Self
                ^
Swift.SequenceType:5:17: note: candidate has non-matching type '<`Self`> () -> `Self`.Base.Generator' (aka '<τ_0_0> () -> τ_0_0.Base.Generator')
    public func generate() -> Self.Generator
                ^
Swift.CollectionType:2:17: note: candidate has non-matching type '<`Self`> () -> IndexingGenerator<`Self`>' (aka '<τ_0_0> () -> IndexingGenerator<τ_0_0>')
    public func generate() -> IndexingGenerator<Self>

Starting from the top, I see we need a type for the associated index type and then there is a whole load of errors that relate to it not being defined, so I add a typealias for protocol Indexable in the extension and that gives me a whole load more errors, so I change CollectionType to Indexable temporarily 从顶部开始,我看到我们需要一个关联索引类型的类型,然后有typealias错误与未定义相关,所以我在扩展中为协议typealias添加了一个typealias ,这给了我一个整体加载更多错误,所以我暂时将CollectionType更改为Indexable

extension BookCollection: Indexable
{
    typealias Index = Int
}

And now i have the following: 现在我有以下内容:

Playground execution failed: MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'Indexable'
extension BookCollection: Indexable
^
Swift.Indexable:21:15: note: protocol requires nested type '_Element'
    typealias _Element
              ^

_Element is supposed to be an implementation detail (it starts with an underscore), but let's roll with it for now and add a type alias for it too. _Element应该是一个实现细节(它以下划线开头),但是现在让我们滚动它并为它添加一个类型别名。

extension BookCollection: Indexable
{
    typealias Index = Int
    typealias _Element = Book
}

Now I have the following 现在我有以下内容

Playground execution failed: MyPlayground.playground:15:1: error: type 'BookCollection' does not conform to protocol 'Indexable'
extension BookCollection: Indexable
^
Swift.Indexable:12:16: note: protocol requires property 'startIndex' with type 'Index' (aka 'Int')
    public var startIndex: Self.Index { get }
               ^
Swift.Indexable:20:16: note: protocol requires property 'endIndex' with type 'Index' (aka 'Int')
    public var endIndex: Self.Index { get }
               ^
Swift.Indexable:22:12: note: protocol requires subscript with type 'Index -> _Element'
    public subscript (position: Self.Index) -> Self._Element { get }

So now I implement the two properties and the subscript. 所以现在我实现了两个属性和下标。 I notice that implementing the subscript would allow the compiler to infer the two type alias types so I can delete those declarations. 我注意到实现下标将允许编译器推断出两种类型的别名类型,因此我可以删除这些声明。

extension BookCollection: Indexable
{
    var startIndex: Int { return books.startIndex }
    var endIndex: Int { return books.endIndex }

    subscript(index: Int) -> Book
    {
        return books[index]
    }
}

This gives no errors, so we change the protocol back to CollectionType and we still have no errors so we must be done. 这没有错误,所以我们将协议更改回CollectionType ,我们仍然没有错误,所以我们必须完成。

There is no easy way other than to use what the compiler errors out on. 除了使用编译器错误之外,没有简单的方法。 Why? 为什么? Because protocols support default implementations and you can't know what protocol functions have a default implementation (except that the compiler does not complain about them). 因为协议支持默认实现,并且您无法知道哪些协议函数具有默认实现(除了编译器不抱怨它们)。

For example, SequenceType has many functions defined. 例如, SequenceType定义了许多函数。 Do you implement them all? 你实现了它们吗? No, because most have default implementations. 不,因为大多数都有默认实现。 The only thing needed is func generate() -> GeneratorType and the associated GeneratorType . 唯一需要的是func generate() -> GeneratorType和相关的GeneratorType After that, your subtype of SequenceType is done - you might choose to override some default implementations, but need not. 之后,您完成了SequenceType的子类型 - 您可能会选择覆盖某些默认实现,但不需要。 For CollectionType it is Indexable (and GeneratorType defaults to IndexingGenerator<Self> ) 对于CollectionType它是Indexable (并且GeneratorType默认为IndexingGenerator<Self>

Of course, if you have the source code, then you can identify the default protocol implementations but, by the time you've done that, you might as well let the compiler tell you. 当然,如果你有源代码,那么你可以识别默认的协议实现,但是,当你完成它时,你也可以让编译器告诉你。 Or, the Apple documentation does list some functions with 'Default Implementation' which might indicate what does not need to be implemented. 或者,Apple文档确实列出了一些带有“默认实现”的功能,这可能表明不需要实现的功能。 Or, as noted in a comment, swiftdoc.org identifies the required types/functions in a clear form. 或者,如评论中所述,swiftdoc.org以清晰的形式标识所需的类型/功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM