Swift 扩展可能不包含存储属性,但为什么允许静态
扩展不能包含存储属性,但为什么可以在扩展中定义静态存储属性 我也没有发现任何文档提到扩展中允许使用静态属性Swift 扩展可能不包含存储属性,但为什么允许静态,swift,swift-extensions,Swift,Swift Extensions,扩展不能包含存储属性,但为什么可以在扩展中定义静态存储属性 我也没有发现任何文档提到扩展中允许使用静态属性 extension String { static let test = "Test" static var test2 = "Test2" } 扩展不能包含存储的实例属性。为什么?因为添加实例属性会更改该类型实例的大小。如果一个模块添加一个扩展名,使得Int现在有两个单词长,会发生什么情况?例如,当它从另一个模块获取一个Int,而该模块的大小仍然为1个单词时,会发生什么情况 扩
extension String {
static let test = "Test"
static var test2 = "Test2"
}
扩展不能包含存储的实例属性。为什么?因为添加实例属性会更改该类型实例的大小。如果一个模块添加一个扩展名,使得
Int
现在有两个单词长,会发生什么情况?例如,当它从另一个模块获取一个Int
,而该模块的大小仍然为1个单词时,会发生什么情况
扩展中允许静态存储属性的原因很简单,因为它们具有静态生存期;它们独立于您要扩展的给定类型的任何实例而存在。实际上,它们只不过是全局存储变量,只是命名为一个类型。因此,可以自由添加它们,而不会影响在不知道它们的情况下已编译的代码
但是值得注意的是,目前定义静态存储属性有三个限制
1.不能在泛型类型上定义静态
存储属性
这将需要对通用占位符的每个单独专业化进行单独的财产存储。例如,使用:
struct S<T> {
static var foo: Int {
return 5
}
static let bar = "" // error: Static stored properties not supported in generic types
}
如果运行时每次以新的S
专门化访问date
时都隐式生成新的存储,则S.date
将不等于S.date
;这可能令人困惑和/或不受欢迎
2.不能在协议扩展中定义静态
存储属性
这主要是从上一点开始的。协议扩展中的static
存储属性需要为该协议的每种符合类型分别存储(但同样,编译器/运行时没有理由不能这样做)
这对于协议是必需的,因为协议扩展中的静态
成员不是协议类型本身的成员。它们是符合协议的具体类型上的成员
例如,如果我们有:
protocol P {}
extension P {
static var foo: Int {
return 5
}
static let bar = "" // error: Static stored properties not supported in generic types
// (not really a great diagnostic)
}
struct S : P {}
struct S1 : P {}
我们无法访问协议类型本身的foo
,我们不能说p.foo
。我们只能说S.foo
或S1.foo
。这很重要,因为foo
的getter可以调用self
上的静态协议需求;但是,如果self
是P.self
(即协议类型本身),这是不可能的
对于静态
存储的属性,如条
,也可能会出现同样的情况
3.不能定义类
存储属性
我不相信在类主体本身中这样的声明会有任何问题(它只相当于由静态
存储属性支持的计算的类
属性)
但是,在扩展中可能会出现问题,因为扩展无法将新成员添加到Swift类vtable(尽管它们可以添加到Obj-C对应项(如果适用))。因此,在大多数情况下,它们不会被动态地分派到(因此实际上是
最终的
,因此静态的
)。尽管如此,class
computed属性目前在扩展中是允许的,因此为了保持一致性,它可能是允许的。Hmm。唯一明确指出的是“Swift中的扩展可以:添加计算实例属性和计算类型属性(…)”他们从来没有提到在扩展中允许存储类型属性,所以我一直认为它们是不允许的。顺便问一下,static var
也同样有效。文档中是否有任何地方指定允许使用static?还是Swift用户必须推断出这一点?@Boon问得好!我找不到任何官方文件说明这一点;但我们可以看一下,它指出“枚举和扩展不能有存储实例属性。允许静态存储属性,但下面强制执行限制。”这些限制适用于1。泛型和2<代码>类存储的属性。可能值得向苹果公司提交一个bug,因为文档中没有提到它。回答得很好。来自scala
我对这里描述的限制有点失望,因为它们都可以用那种语言轻松处理。但这并不会降低内容的质量。
protocol P {}
extension P {
static var foo: Int {
return 5
}
static let bar = "" // error: Static stored properties not supported in generic types
// (not really a great diagnostic)
}
struct S : P {}
struct S1 : P {}