为什么不能初始化具有默认实现的协议?
Why can't you initialize a protocol that has default implementation?
我已阅读
我的问题集中在为什么编译器不能查看您的默认实现并基于它初始化对象?
protocol ViewModel {
var radius: Int { get }
init()
}
extension ViewModel {
var radius: Int { return 2}
init() {}
}
let v = ViewModel() // ERROR:
Protocol type 'ViewModel' cannot be instantiated
问题一:
为什么 Swift 不允许对协议进行原始初始化?为什么它必须绑定到具体类型?
我知道它不是具体类型。但是为什么编译器不允许你只创建一个类型,它只是默认值中的协议?!是不是因为编译器就像嘿听着,而我可以 将您视为 interface/protocol 或实际类型。我不能把你当成两者!?你要么是记忆中的真实事物,要么只是一个蓝图。
如果语言可以检查扩展是否为所有需求提供了实现,那么允许将其初始化为特殊情况是否有意义? (我知道它没有,但想知道的是唯一需要让它工作的东西)或者即使那样这也没有意义。如果是,为什么?
此外,我尝试这样做:
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' isn't called on all paths before returning from
initializer
问题2:
为什么?为什么 init
必须调用 self.init()
看起来有点像递归循环。
https://docs.swift.org/swift-book/LanguageGuide/Protocols.html
协议是蓝图,不包含实现 - 因此您无法初始化它们。
A class 同意协议并且必须提供实际实施。
协议不是具体类型,因此当您调用 Protocol.init()
时,编译器不知道要初始化什么具体类型。它只会知道您要初始化的类型具有 Protocol
.
描述的接口
由于内存分配,编译器必须知道具体类型。协议仅定义其一致性类型必须具有的必需属性(和方法)的子集,但不定义其一致性类型将具有的整组属性,因为这实际上因类型而异。因此,如果您能够初始化协议类型,编译器和运行时将不知道为该特定对象分配多少内存,这是一条信息,没有它就无法初始化任何对象。
这与ViewModel是否有init
无关。它与 ViewModel 是 的内容有关。这是一个协议。
协议不是对象。 没有 协议的实例。 "instantiate" 协议意味着什么?没有什么。您可以创建一个实例:
- 枚举
- 一个结构
- 或 class
协议是其中的 none。您不能创建协议实例。
ViewModel 是一种协议。所以你不能创建它的实例。短语 ViewModel()
没有意义。编译器告诉你的。
我已阅读
我的问题集中在为什么编译器不能查看您的默认实现并基于它初始化对象?
protocol ViewModel {
var radius: Int { get }
init()
}
extension ViewModel {
var radius: Int { return 2}
init() {}
}
let v = ViewModel() // ERROR:
Protocol type 'ViewModel' cannot be instantiated
问题一:
为什么 Swift 不允许对协议进行原始初始化?为什么它必须绑定到具体类型?
我知道它不是具体类型。但是为什么编译器不允许你只创建一个类型,它只是默认值中的协议?!是不是因为编译器就像嘿听着,而我可以 将您视为 interface/protocol 或实际类型。我不能把你当成两者!?你要么是记忆中的真实事物,要么只是一个蓝图。
如果语言可以检查扩展是否为所有需求提供了实现,那么允许将其初始化为特殊情况是否有意义? (我知道它没有,但想知道的是唯一需要让它工作的东西)或者即使那样这也没有意义。如果是,为什么?
此外,我尝试这样做:
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' isn't called on all paths before returning from initializer
问题2:
为什么?为什么 init
必须调用 self.init()
看起来有点像递归循环。
https://docs.swift.org/swift-book/LanguageGuide/Protocols.html
协议是蓝图,不包含实现 - 因此您无法初始化它们。
A class 同意协议并且必须提供实际实施。
协议不是具体类型,因此当您调用 Protocol.init()
时,编译器不知道要初始化什么具体类型。它只会知道您要初始化的类型具有 Protocol
.
由于内存分配,编译器必须知道具体类型。协议仅定义其一致性类型必须具有的必需属性(和方法)的子集,但不定义其一致性类型将具有的整组属性,因为这实际上因类型而异。因此,如果您能够初始化协议类型,编译器和运行时将不知道为该特定对象分配多少内存,这是一条信息,没有它就无法初始化任何对象。
这与ViewModel是否有init
无关。它与 ViewModel 是 的内容有关。这是一个协议。
协议不是对象。 没有 协议的实例。 "instantiate" 协议意味着什么?没有什么。您可以创建一个实例:
- 枚举
- 一个结构
- 或 class
协议是其中的 none。您不能创建协议实例。
ViewModel 是一种协议。所以你不能创建它的实例。短语 ViewModel()
没有意义。编译器告诉你的。