【问题标题】:Extension of protocol with method which adds default parameter使用添加默认参数的方法扩展协议
【发布时间】:2018-01-12 17:52:01
【问题描述】:

我习惯于在使用扩展的协议中使用默认参数,因为协议声明本身不能拥有它们,如下所示:

protocol Controller {
   func fetch(forPredicate predicate: NSPredicate?)
}

extension Controller {
   func fetch(forPredicate predicate: NSPredicate? = nil) {
      return fetch(forPredicate: nil)
   }
}

非常适合我。

现在我有下一种情况,我有一个特定类型的控制器的特定协议:

protocol SomeSpecificDatabaseControllerProtocol {
    //...
    func count(forPredicate predicate: NSPredicate?) -> Int
}

以及带有控制器默认方法实现的协议扩展:

protocol DatabaseControllerProtocol {
    associatedtype Entity: NSManagedObject
    func defaultFetchRequest() -> NSFetchRequest<Entity>
    var context: NSManagedObjectContext { get }
}

extension DatabaseControllerProtocol {
    func save() {
        ...
    }

    func get() -> [Entity] {
        ...
    }

    func count(forPredicate predicate: NSPredicate?) -> Int {
        ...
    }

    //.....
}

我的问题是,当我尝试将带有默认参数的方法添加到 SomeSpecificDatabaseControllerProtocol 扩展时,我收到编译时错误,符合 SomeSpecificDatabaseControllerProtocol 的具体类不符合协议(只有当我扩展协议时才会发生):

class SomeClassDatabaseController: SomeSpecificDatabaseControllerProtocol, DatabaseControllerProtocol {...}

我错过了什么?

【问题讨论】:

    标签: swift swift-protocols swift-extensions


    【解决方案1】:

    发生这种情况是因为编译器由于函数不明确而混淆。

    1. 这里SomeClassDatabaseController 接收来自两个不同协议的count() 方法。

    2. DatabaseControllerProtocolcount(forPredicate) 方法,总是需要参数。

    3. 另一方面,SomeSpecificDatabaseControllerProtocolcount() 方法,可以有空参数。

    4. 要解决此问题,您必须将DatabaseControllerProtocol 中的计数方法更改为此,或者您必须在SomeClassDatabaseController 中实现它。

    func count(forPredicate predicate: NSPredicate? = nil) -&gt; Int { return 0}

    【讨论】:

    • 是的,没错,这就是我刚刚理解的:) 最轻松的方法是用DatabaseControllerProtocol声明更改func的接口
    • 有时我们需要更具体。我们不能总是依赖工具。或者必须离开来指定它应该调用哪个类方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多