Swift元组访问级别规则困惑:为何需显式声明fileprivate?
Swift元组访问控制的细节解惑
问题核心
你提到的官方规则没错,但忽略了Swift中private访问级别在不同声明位置的作用域差异,这才是导致编译器报错的关键。
先回顾你的测试代码:
public class Main{ var value1 : Int = 4 } fileprivate class Main2{ var value2: Int = 4 } private class Main3{ var value3 : Int = 4 } public class tupleExample { var tupleIs = (Main(),Main2(),Main3()) // 默认访问级别为internal }
编译器要求将tupleIs声明为fileprivate,而非预期的private,原因如下:
关键细节:private的作用域分两种
Swift里的private并非单一作用域:
- 类型内部声明的
private:作用域仅限该类型内部,这是最严格的访问级别。 - 顶层(文件级)声明的
private:作用域等同于fileprivate,即整个文件内都可访问——因为顶层没有更小的封装上下文,private只能退化为文件级访问。
你的代码中,private class Main3是在文件顶层声明的,它的实际访问权限和fileprivate class Main2完全一致。
元组访问级别的推导逻辑
元组的访问级别取组成类型中最严格且作用域兼容的级别:
- 你的元组包含
public(Main)、fileprivate(Main2)、顶层private(等价fileprivate,Main3)三种类型。 - 最严格的有效级别是
fileprivate,而非你以为的private。 - 属性
tupleIs默认访问级别是internal,比fileprivate宽松,因此编译器报错,要求你将属性声明为fileprivate以匹配元组的访问级别。
验证:换个场景看差异
如果把Main3放到tupleExample类内部声明为private,情况就会符合你最初的预期:
public class Main{ var value1 : Int = 4 } fileprivate class Main2{ var value2: Int = 4 } public class tupleExample { private class Main3{ var value3 : Int = 4 } // 此时必须声明为private,否则编译器报错 private var tupleIs = (Main(),Main2(),Main3()) }
这时Main3是类内部的private,作用域仅限tupleExample内部,元组的访问级别被推导为private,属性必须声明为private才能满足权限要求。
内容的提问来源于stack exchange,提问作者Omer Tekbiyik
相关产品推荐
相关产品推荐

