Swift:使用默认值符合协议

时间:2018-10-25 10:39:53

标签: ios swift

有没有办法使用默认值符合Swift协议?

以下示例产生一个Type 'FunExample' does not conform to protocol 'Example'

protocol Example {
    func doSomething(with: String)
}

class FunExample: Example {
    func doSomething(with: String, butMakeItFun: Bool = true) {
        // implementation
    }
}

...尽管我实际上隐含地遵循,因为这与以下内容相同:

protocol Example {
    func doSomething(with: String)
}

class FunExample: Example {
    func doSomething(with: String) {
        self.doSomething(with: with, butMakeItFun: true)
    }
    func doSomething(with: String, butMakeItFun: Bool) {
        // implementation
    }
}

是否有一种更干净的方法来使用默认值提供一致性?或者当我说第一个示例应该也通过一致性时,我在概念上是否缺少某些东西?

要澄清一下:我理解为什么会产生错误。我的问题是更具概念性的(Swift 是否应该以这种方式工作)以及是否有一种优雅的解决方法。

3 个答案:

答案 0 :(得分:2)

您可以选择extension,以使用更简洁的方法!使用相同的extension方法制作一个protocol,并传递所需的默认值。假设:

protocol Example { //Main Protocol
    func doSomething(with: String, butMakeItFun: Bool)
}

extension Example { //Make to pass the default values if you want
    func doSomething(with: String, butMakeItFun: Bool = false) {
        return doSomething(with: with, butMakeItFun: butMakeItFun)
    }
}

class FunExample: Example { //Protocol Acceptance
    func doSomething(with: String, butMakeItFun: Bool) {
        debugPrint("\(with)")
        debugPrint(butMakeItFun)
    }
}

您可以通过以下方式调用它:

  1. FunExample().doSomething(with: "Hello Default Values...")
  2. FunExample().doSomething(with: "..........", butMakeItFun: true)
  

更新

因此,根据您的评论,这就是我的想法!您可以在protocol下使用一个变量,该变量肯定是truefalse作为默认实现,以后您可以在class中对其进行更改。

protocol Example {
    var isFun: Bool {set get}
    func doSomething(with: String)
}

class FunExample: Example {

    //var isFun: Bool = false - In case you want to change value

    func doSomething(with: String) {
        doSomething(with: with, butMakeItFun: isFun)
    }

    func doSomething(with: String, butMakeItFun: Bool) {
        debugPrint(with)
        debugPrint(butMakeItFun)
    }
}

extension Example {
    var isFun: Bool {
        get { return true /* Your Default Value */ } set {}
    }
}

答案 1 :(得分:1)

在编写示例代码时,您的FunExample不符合要求,因为它没有函数func doSomething(with: String)

func doSomething(with: String)func doSomething(with: String, butMakeItFun: Bool)不同。因此不符合。

添加以下代码后,它将符合要求

func doSomething(with: String) {
    self.doSomething(with: with, butMakeItFun: true)
}

我将提供doSomething(with:String)的默认实现,然后在需要的地方“装饰”它。

protocol Example {
    func doSomething(with: String)
}

extension Example {
    func doSomething(with text: String) {
        print(text)
    }
}

class FunExample: Example {
    func doSomething(with: String, butMakeItFun: Bool) {

        if butMakeItFun() {
          playTheSound()
          releaseBalloons()
        }

        return doSomething(with: String)
    }
}

答案 2 :(得分:0)

经过研究和思考,事实证明,Swift not 支持这一点在概念上是正确的。

协议一致性的思想是确保您的类符合某些要求,并且可以毫无问题地提供该功能。如果存在隐式一致性,则无法实现。

为什么?考虑原始示例,对其进行了一些修改:

protocol Example {
    func doSomething(with: String)
}

class FunExample: Example {
    func doSomething(with: String, butMakeItFun: Bool = true) {
        // implementation
    }
    func doSomething(with: String, andDoSomeOtherStuffWith parameter: String = "") {
        // another implementation
    }
}

如果由于默认值,Swift假设func doSomething(with: String, butMakeItFun: Bool = true)符合func doSomething(with: String),那么这会引起歧义(因为另一个doSomething函数也符合)。 / p>

换句话说,这里FunExample实际上并未隐式实现功能doSomething(with: "Asdf"),因为仅在类上调用此函数将导致Ambiguous use of 'doSomething'错误。

因此,从概念上讲不可能依靠默认值隐式地假定协议符合性。