可见性(Visibility)
可见性修饰符分两个域:顶层域管模块里的顶层声明,成员域管类型成员。
封装单位逐级对齐:private 对类型、internal 对模块、package 对包内开放、public 对所有外部全开放。
五个修饰符
| 修饰符 | 语义 |
|---|---|
private | 当前词法作用域及向下子嵌套(仅成员位) |
internal | 模块内可见(partial 合并的兄弟文件互见) |
derived | 纯继承链可见(仅成员位) |
package | 当前包内可见 |
public | 全可见 |
顶层域只收三档:internal < package < public,顶层无法写 private / derived。顶层无修饰时,默认为 package 可见性。成员域五档都可以写,成员无修饰默认为 private。
internal:模块边界
module App;
internal func Secret() -> string => "模块内密";
public func Api() -> string => "公开面";
func main() -> int
{
print(Api(), Secret());
return 0;
}公开面 模块内密本模块内 Secret 可直接调用,internal 的作用域是本模块。其他模块(哪怕经 import Extra.*; 拿到短名)也无法调用。
跨包场景同律:FQR 全限定名也不绕过可见性,跨包无法访问非 public 成员。
derived:继承链可见
derived 成员对派生类可见、对外不可见,是横跨类型边界的继承通道:
class Base
{
derived func Hook() -> string => "钩子";
}
class Child : Base
{
public func Use() -> string => Hook();
}
func main() -> int
{
print(new Child().Use());
return 0;
}钩子Child 里能调 Hook,类外不行。与 internal 的差别:internal 放行整个模块(不管类型关系),derived 只放行继承链。
package 与 public
internal func Modi() -> string => "仅本模块";
package func Pkgi() -> string => "全包可用";
public func Open() -> string => "谁都能用";同包跨模块调用 Pkgi() 合法(模块 B 引用模块 A 的 package 成员),跨包就只剩 public。发布成库时,public 就是 API 面。
注意
- 可见性写在声明前缀位:
public func/internal val/public class,与 static、属性前缀的组合顺序固定(属性 → 可见性 → static → 其余)。 - 类型成员跨类型访问遵循成员域,同类型内部 private 通吃。
- partial module 合并的兄弟文件互见 internal 成员,合并发生在可见性判定之前。
最后更新于 2026年10月10日
