Versions/v1.1.0/中文

顶层声明的可见性

Sections1
On This Page1
API Symbols11

顶层声明的可见性

仓颉编程语言中,可以使用访问修饰符来控制对类型、变量、函数等顶层声明的可见性。仓颉语言有 4 种访问修饰符:privateinternalprotectedpublic,在修饰顶层元素时不同访问修饰符的语义如下:

- private 表示仅当前文件内可见。不同的文件无法访问这类成员。
- internal 表示仅当前包及子包(包括子包的子包)内可见。同一个包内可以不导入就访问这类成员,当前包的子包(包括子包的子包)内可以通过导入来访问这类成员。
- protected 表示仅当前模块内可见。同一个包的文件可以不导入就访问这类成员,不同包但是在同一个模块内的其他包可以通过导入访问这些成员,不同模块的包无法访问这些成员。
- public 表示模块内外均可见。同一个包的文件可以不导入就访问这类成员,其他包可以通过导入访问这些成员。

| 修饰符 | 文件 | 包及子包 | 模块 | 所有包 |
|-------------|------|----------|------|--------|
| private | Y | N | N | N |
| internal | Y | Y | N | N |
| protected | Y | Y | Y | N |
| public | Y | Y | Y | Y |

不同顶层声明支持的访问修饰符和默认修饰符(默认修饰符是指在省略情况下的修饰符语义,这些默认修饰符也允许显式写出)规定如下:

- package 支持使用 internalprotectedpublic,默认修饰符为 public
- import 支持使用全部访问修饰符,默认修饰符为 private
- 其他顶层声明支持使用全部访问修饰符,默认修饰符为 internal

仓颉的访问级别排序为 public > protected > internal > private。一个声明的访问修饰符不得高于该声明中用到的类型的访问修饰符的级别,参考如下示例:

- 函数声明中的参数与返回值

- 变量声明

- 泛型类型的类型实参

- where 约束中的类型上界

值得注意的是:

- public 修饰的声明在其初始化表达式或者函数体里面可以使用本包可见的任意类型,包括被 public 修饰的类型和不被 public 修饰的类型。

- public 修饰的顶层声明能使用匿名函数,或者任意顶层函数,包括被 public 修饰的类型和不被 public 修饰的顶层函数。

- 内置类型诸如 RuneInt64 等默认的修饰符是 public

> 注意:
>
> 同一个包内,private 修饰的同名自定义类型(如 structclassenuminterface 等),在某些场景下不支持,不支持场景由编译器进行报错。

例如在以下程序中,example1.cjexample2.cj文件包名相同,在 example1.cj 文件中定义了 private 修饰的类 A, 在 example2.cj 文件中定义了 private 修饰的结构体 A

运行以上程序,将输出:

cangjie
package a

private func f1() { 1 }   // f1 仅在当前文件内可见
func f2() { 2 }           // f2 仅当前包及子包内可见
protected func f3() { 3 } // f3 仅当前模块内可见
public func f4() { 4 }    // f4 当前模块内外均可见
cangjie
// example1.cj
package test

private class A {}

public class D<T> {
    private let a: A = A()
}
cangjie
// example2.cj
package test

private struct A {}

public class C<T> {
    private let a: A = A()
}
text
error: currently, it is not possible to export two private declarations with the same name