在Apple文档中:
- 在扩展中添加的任何类型成员都具有与要扩展的原始类型中声明的类型成员相同的默认访问级别。如果扩展公共或内部类型,则添加的任何新类型成员都将具有默认访问级别internal。*
给出UIView扩展的子类:
extension UIViewSubClass
{
var helloWorld : String {
get {
return "helloWorld"
}
}
}
这会将helloWorld
标记为内部的,我没有问题,而且我在基于Objective-C的项目中看不到它。
但是,如果我将扩展标记为public:
public extension UIViewSubClass
{
var helloWorld : String {
get {
return "helloWorld"
}
}
}
现在helloWorld
出现在我基于Objective-C的代码中,这意味着它被标记为public。
但是,我没有看到苹果提到这一点,是吗?
我刚刚看到文档说一个公共类仍然会有隐式的内部级别。
public class SomePublicClass { // explicitly public class
public var somePublicProperty = 0 // explicitly public class member
var someInternalProperty = 0 // implicitly internal class member
private func somePrivateMethod() {} // explicitly private class member
}
将扩展标记为公共似乎与标记一个类定义有不同的效果。这让我很困惑。
有人能帮帮我吗,这是应该的,还是这是一个swift的bug?我用的是swift 2.1和Xcode 7.2
1条答案
按热度按时间gijlo24d1#
**答案:**是的,在扩展前面放置访问级别修饰符(在您的情况下,具体为
public
),修改 * 该扩展范围内所有新类型的默认访问级别 *。注意修饰符并不影响被扩展的类/结构/etc的访问级别(只影响其成员)。然而,有一些事情应该考虑,正如我将在下面讨论的那样。
在这次讨论中,我将发布一些关于Swift中访问级别的重要事实。所有这些都来自Swift Language Guide - Access Control - Access Levels。
让我们先确认一下你已经说过的话:
如果您自己没有指定显式访问级别,则代码中的所有实体(如本章后面所述,有几个特定的例外)都具有默认访问级别internal。
好的,这与你在问题中引用的内容一致:任何 new 类型成员,无论是在类还是结构定义中,都将具有 default 访问级别internal。
现在,让我们看看您可以在扩展前面添加的访问级别修饰符:
可以在类、结构或枚举可用的任何访问上下文中扩展该类、结构或枚举。在扩展中添加的任何类型成员都具有与要扩展的原始类型中声明的类型成员相同的默认访问级别。* 如果扩展公共或内部类型,您添加的任何新类型成员都将具有默认访问级别internal。如果扩展private类型,则您添加的任何新类型成员都将具有默认访问级别private。*
或者,可以使用显式访问级别修饰符标记扩展(例如,私有扩展),以便为扩展中定义的所有成员设置新的默认访问级别。在扩展中,仍可为单个类型成员覆盖此新的默认值。
我们看一下你的例子,并假设你的类
UIViewSubClass
的访问级别为public
(或编译时错误,如下所示):考虑到上面的讨论,
public extension ...
中的helloWorld
应该被标记为internal
,因为在此上下文中,这是默认的访问级别。在扩展的上下文中,访问级别修饰符的工作方式与应用于类型时不同。最后,我们应该指出,在扩展非公有类时使用
public
访问修饰符将在Swift中产生编译时错误。所以在上面的例子中:UISubViewClass
是internal
或private
类,则该类上的public extension ...
将产生编译时错误。UISubViewClass
是一个public
类,那么添加public extension
将是多余的,因为根据定义,公共类的默认访问修饰符已经是public
。我要说的是,上面描述的错误并不是为了避免运行时错误,而是为了避免冗余(和混乱)的代码:
public
成员类型或private
或internal
类永远不会使用其public
访问级别。因此,只有在扩展上使用访问级别修饰符来 * 使默认访问级别更具限制性 * 才有意义,即使用
public
类的internal extension ...
,或private extension
或internal
类。