-1

我已经阅读了In swift,为什么我不能实例化具有初始化程序的协议?

我的问题集中在为什么编译器不能查看您的默认实现并基于它初始化对象?

protocol ViewModel {
    var radius: Int { get }
    init()
}

extension ViewModel {
    var radius: Int { return 2}
    init() {}
}

let v = ViewModel() // ERROR: 

无法实例化协议类型“ViewModel”

问题1:

为什么 Swift 不允许协议的原始初始化?为什么它必须与具体类型相关联?

我知道它不是一个具体的类型。但是为什么编译器不允许你创建一个只有协议默认值的类型呢?!是不是因为编译器就像嘿听一样,而我可以您视为接口/协议或实际类型。我不能认为你们两个!?你要么是记忆中的真实存在,要么只是一个蓝图。

如果语言可以检查扩展是否为所有需求提供了实现,那么允许将其初始化为特殊情况是否有意义?(我知道它没有,但想知道的是唯一需要让它工作)或者即使那样这也没有意义。如果是,为什么?

此外,我尝试这样做:

protocol ViewModel {
    var radius: Int { get }
    init()
}

extension ViewModel {
    var radius: Int { return 2}
    init() {
        self.init() // Line A: 
    }
}

struct ReallyNothing: ViewModel {}

let v = ReallyNothing()

如果我注释掉 LineA 那么我会得到一个错误

在从初始化程序返回之前,不会在所有路径上调用“self.init”

问题2:

为什么?为什么init必须调用self.init()它似乎有点像递归循环。

4

3 回答 3

1

协议不是具体类型,因此当您调用 时Protocol.init(),编译器不知道要初始化什么具体类型。它只会知道您要初始化的类型具有由 描述的接口Protocol

由于内存分配,编译器必须知道具体类型。协议只定义了其符合类型必须具有的所需属性(和方法)的子集,但没有定义其符合类型将具有的全部属性集,因为这实际上因类型而异。因此,如果您能够初始化协议类型,编译器和运行时将不知道要为该特定对象分配多少内存,这是一条信息,没有它就无法初始化任何对象。

于 2019-11-11T23:40:42.947 回答
1

这与 ViewModel 是否具有init. 它与 ViewModel什么有关。这是一个协议。

协议不是对象。没有协议实例这样的东西。“实例化”协议意味着什么?没有。您可以创建一个实例:

  • 一个枚举
  • 一个结构
  • 或一堂课

协议不是这些。您不能创建协议的实例。

ViewModel 是一个协议。所以你不能做一个实例。这句话ViewModel()毫无意义。编译器会告诉你。

于 2019-11-12T00:08:49.490 回答
0

https://docs.swift.org/swift-book/LanguageGuide/Protocols.html

协议是蓝图,不包含实现——所以你不能初始化它们。

一个类同意协议并且必须提供实际的实现。

于 2019-11-11T23:12:36.930 回答