首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协议扩展初始化程序强制调用self.init

协议扩展初始化程序强制调用self.init
EN

Stack Overflow用户
提问于 2018-05-10 09:58:58
回答 1查看 3K关注 0票数 5

我刚刚阅读了Apple 4关于协议初始化器需求的文档,并在协议扩展中提供了默认实现。

代码语言:javascript
复制
import UIKit
protocol Protocol {
    init()
}
extension Protocol {
    init() {
        print("SDf")
        self.init() // Line 1
                    // 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行,编译器就会给出错误。

问:为什么它强迫我在1号线上使用self.init(),以及如何摆脱这种情况?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-10 17:04:48

考虑一下这个例子:

代码语言:javascript
复制
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。它需要您链接到其他初始化器需求--您没有为其提供默认实现(否则您可以进入递归循环,正如您所发现的那样),因此采用类型需要实现,以便能够完全初始化自己。

例如,这是合法的:

代码语言:javascript
复制
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必须实现这个需求(在本例中,它是由隐式元初始化满足的)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50270261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档