Protocol Extention Initializer强制调用self.init

时间:2018-05-10 09:58:58

标签: swift swift-protocols

我刚刚阅读了有关协议初始化程序要求的Apple Swift 4文档,并在协议扩展中提供了默认实现。

import UIKit
protocol Protocol {
    init()
}
extension Protocol {
    init() {
        print("SDf")
        self.init() // Line 2
                    // Compiler error occured if this is omitted 
                    //"'self.init' isn't called on all paths before returning from initializer"
    }
}

struct Structure: Protocol {
    init(string: String) {

    }
}

Structure()      // Line 2

现在你可以看到,执行将进入循环,因为默认情况下结构没有init()的实现,所以提供的init协议将被调用,它再次调用自己并进入无限循环。

现在,知道这一点,如果我删除第1行,编译器会给出错误。

Q值。为什么强制在第1行使用self.init()以及如何摆脱这种情况呢?

1 个答案:

答案 0 :(得分:3)

考虑这个例子:

protocol P {
  init()
}

extension P {
  init() {

  } // error: 'self.init' isn't called on all paths before returning from initializer
}

struct S : P {
  var str: String
}

let s = S()
print(s.str)

假设已编译 - 我们可以创建S值而无需为str属性提供值。这就是为什么编译器抱怨init()的协议扩展实现没有调用self.init的原因。它需要你链接到一些其他的初始化者需求 - 你没有提供一个默认实现(否则你可能会进入一个递归循环,如你所知),因此采用类型需要实现,以便它可以完全初始化。

例如,这是合法的:

protocol P {
  init()
  init(str: String)
}

extension P {
  init() {
    self.init(str: "some default")
  }
}

struct S : P {
  var str: String
}

let s = S()
print(s.str) // some default

因为现在我们正在链接到init(str:) 必须实施的S要求(在这种情况下,{{3}满足}})。