Package Import
Inspect one language lane at a time so line-level text and code deltas stay readable.
Diff Lane
English
0 modified sections0 code block delta0 anchor delta
Diff Lane
中文
3 modified sections0 code block delta0 anchor delta
modified使用 `import` 语句导入其他包中的声明或定义textcode+4 lines
v1.0.5
Section Text
1
在仓颉编程语言中,可以通过 `import fullPackageName.itemName` 的语法导入其他包中的一个顶层声明或定义,`fullPackageName` 为完整路径包名,`itemName` 为声明的名字。导入语句在源文件中的位置必须在包声明之后,其他声明或定义之前。例如:2
3
4
如果要导入的多个 `itemName` 同属于一个 `fullPackageName`,可以使用 `import fullPackageName.{itemName[, itemName]*}` 语法,例如:5
6
7
这等价于:8
9
10
除了通过 `import fullPackagename.itemName` 语法导入一个特定的顶层声明或定义外,还可以使用 `import packageName.*` 语法将 `packageName` 包中所有可见的顶层声明或定义全部导入。例如:11
12
13
需要注意:14
15
- 导入的成员的作用域级别低于当前包声明的成员。16
- 当已导出的包的模块名或者包名被篡改,使其与导出时指定的模块名或包名不一致,在导入时会报错。17
- 只允许导入当前文件可见的顶层声明或定义,导入不可见的声明或定义将会在导入处报错。18
- 禁止通过 `import` 导入当前源文件所在包的声明或定义。19
- 禁止包间的循环依赖导入,如果包之间存在循环依赖,编译器会报错。20
21
示例如下:22
23
24
在仓颉编程语言中,导入的声明或定义如果和当前包中的顶层声明或定义重名且不构成函数重载,则导入的声明和定义会被遮盖;导入的声明或定义如果和当前包中的顶层声明或定义重名且构成函数重载,函数调用时将会根据函数重载的规则进行函数决议。Code 1 · cangjie
1
package a2
import std.math.*3
import package1.foo4
import {package1.foo, package2.bar}Code 2 · cangjie
1
import package1.{foo, bar, fuzz}Code 3 · cangjie
1
import package1.foo2
import package1.bar3
import package1.fuzzCode 4 · cangjie
1
import package1.*2
import {package1.*, package2.*}Code 5 · cangjie
1
// pkga/a.cj2
package pkga // Error, packages pkga pkgb are in circular dependencies.3
import pkgb.*4
5
class C {}6
public struct R {}7
8
// pkgb/b.cj9
package pkgb10
11
import pkga.*12
13
// pkgc/c1.cj14
package pkgc15
16
import pkga.C // Error, 'C' is not accessible in package 'pkga'.17
import pkga.R // OK, R is an external top-level declaration of package pkga.18
import pkgc.f1 // Error, package 'pkgc' should not import itself.19
20
public func f1() {}21
22
// pkgc/c2.cj23
package pkgc24
25
func f2() {26
/* OK, the imported declaration is visible to all source files of the same package27
* and accessing import declaration by its name is supported.28
*/29
R()30
31
// OK, accessing imported declaration by fully qualified name is supported.32
pkga.R()33
34
// OK, the declaration of current package can be accessed directly.35
f1()36
37
// OK, accessing declaration of current package by fully qualified name is supported.38
pkgc.f1()39
}Code 6 · cangjie
1
// pkga/a.cj2
package pkga3
4
public struct R {} // R15
public func f(a: Int32) {} // f16
public func f(a: Bool) {} // f27
8
// pkgb/b.cj9
package pkgb10
import pkga.*11
12
func f(a: Int32) {} // f313
struct R {} // R214
15
func bar() {16
R() // OK, R2 shadows R1.17
f(1) // OK, invoke f3 in current package.18
f(true) // OK, invoke f2 in the imported package19
}Code 7 · cangjie
1
v1.1.0
Section Text
1
在仓颉编程语言中,可以通过 `import fullPackageName.itemName` 的语法导入其他包中的一个顶层声明或定义,`fullPackageName` 为完整路径包名,`itemName` 为声明的名字。导入语句在源文件中的位置必须在包声明之后,其他声明或定义之前。例如:2
3
<!-- code_check_manual -->4
5
6
如果要导入的多个 `itemName` 同属于一个 `fullPackageName`,可以使用 `import fullPackageName.{itemName[, itemName]*}` 语法,例如:7
8
<!-- code_check_manual -->9
10
11
这等价于:12
13
<!-- code_check_manual -->14
15
16
除了通过 `import fullPackagename.itemName` 语法导入一个特定的顶层声明或定义外,还可以使用 `import packageName.*` 语法将 `packageName` 包中所有可见的顶层声明或定义全部导入。例如:17
18
<!-- code_check_manual -->19
20
21
需要注意:22
23
- 导入的成员的作用域级别低于当前包声明的成员。24
- 当已导出的包的模块名或者包名被篡改,使其与导出时指定的模块名或包名不一致,在导入时会报错。25
- 只允许导入当前文件可见的顶层声明或定义,导入不可见的声明或定义将会在导入处报错。26
- 禁止通过 `import` 导入当前源文件所在包的声明或定义。27
- 禁止包间的循环依赖导入,如果包之间存在循环依赖,编译器会报错。28
29
示例如下:30
31
<!-- code_check_manual -->32
33
34
在仓颉编程语言中,导入的声明或定义如果和当前包中的顶层声明或定义重名且不构成函数重载,则导入的声明和定义会被遮盖;导入的声明或定义如果和当前包中的顶层声明或定义重名且构成函数重载,函数调用时将会根据函数重载的规则进行函数决议。35
36
<!-- compile -over_res -->37
<!-- cfg="-p pkga --output-type=staticlib"-->38
39
40
<!-- compile -over_res -->41
<!-- cfg="-p pkgb libpkga.a --output-type=staticlib"-->Code 1 · cangjie
1
package a2
import std.math.*3
import package1.foo4
import {package1.foo, package2.bar}Code 2 · cangjie
1
import package1.{foo, bar, fuzz}Code 3 · cangjie
1
import package1.foo2
import package1.bar3
import package1.fuzzCode 4 · cangjie
1
import package1.*2
import {package1.*, package2.*}Code 5 · cangjie
1
// pkga/a.cj2
package pkga // Error, packages pkga pkgb are in circular dependencies.3
import pkgb.*4
5
class C {}6
public struct R {}7
8
// pkgb/b.cj9
package pkgb10
11
import pkga.*12
13
// pkgc/c1.cj14
package pkgc15
16
import pkga.C // Error, 'C' is not accessible in package 'pkga'.17
import pkgc.f1 // Error, package 'pkgc' should not import itself.18
19
public func f1() {}20
21
// pkgc/c2.cj22
package pkgc23
24
import pkga.R // OK, R is an external top-level declaration of package pkga.25
import pkga26
27
func f2() {28
/* OK, the imported declaration is visible to all source files of the same package29
* and accessing import declaration by its name is supported.30
*/31
R()32
33
// OK, accessing imported declaration by fully qualified name is supported.34
pkga.R()35
36
// OK, the declaration of current package can be accessed directly.37
f1()38
}Code 6 · cangjie
1
// pkga/a.cj2
package pkga3
4
public struct R {} // R15
public func f(a: Int32) {} // f16
public func f(a: Bool) {} // f2Code 7 · cangjie
1
// pkgb/b.cj2
package pkgb3
4
import pkga.*5
6
func f(a: Int32) {} // f37
struct R {} // R28
9
func bar() {10
R() // OK, R2 shadows R1.11
f(1) // OK, invoke f3 in current package.12
f(true) // OK, invoke f2 in the pkga13
}modified使用 `import as` 对导入的名字重命名text+4 lines
v1.0.5
Section Text
1
不同包的名字空间是分隔的,因此在不同的包之间可能存在同名的顶层声明。在导入不同包的同名顶层声明时,支持使用 `import packageName.name as newName` 的方式进行重命名来避免冲突。没有名字冲突的情况下仍然可以通过 `import as` 来重命名导入的内容。`import as` 具有如下规则:2
3
- 使用 `import as` 对导入的声明进行重命名后,当前包只能使用重命名后的新名字,原名无法使用。4
- 如果重命名后的名字与当前包顶层作用域的其他名字存在冲突,且这些名字对应的声明均为函数类型,则参与函数重载,否则报重定义的错误。5
- 支持 `import pkg as newPkgName` 的形式对包名进行重命名,以解决不同模块中同名包的命名冲突问题。6
<!-- compile.error -import3-->7
<!-- cfg="-p p1 --output-type=staticlib" -->8
9
```cangjie10
// a.cj11
package p112
public func f1() {}13
```14
15
<!-- compile.error -import3-->16
<!-- cfg="-p p2 --output-type=staticlib" -->17
18
```cangjie19
// d.cj20
package p221
public func f3() {}22
```23
24
<!-- compile.error -import3-->25
<!-- cfg="-p p1 --output-type=staticlib" -->26
27
```cangjie28
// b.cj29
package p130
public func f2() {}31
```32
33
<!-- compile.error -import3-->34
<!-- cfg="-p pkgc --output-type=staticlib" -->35
36
```cangjie37
// c.cj38
package pkgc39
public func f1() {}40
```41
42
<!-- compile.error -import3-->43
<!-- cfg="libp1.a libpkgc.a libp1.a" -->44
45
```cangjie46
// main.cj47
import p1 as A48
import p1 as B49
import p2.f3 as f // OK50
import pkgc.f1 as a51
import pkgc.f1 as b // OK52
53
func f(a: Int32) {}54
55
main() {56
A.f1() // OK, package name conflict is resolved by renaming package name.57
B.f2() // OK, package name conflict is resolved by renaming package name.58
p1.f1() // Error, the original package name cannot be used.59
a() // OK.60
b() // OK.61
pkgc.f1() // Error, the original name cannot be used.62
}63
```64
65
- 如果没有对导入的存在冲突的名字进行重命名,在 `import` 语句处不报错;在使用处,会因为无法导入唯一的名字而报错。这种情况可以通过 `import as` 定义别名或者 `import fullPackageName` 导入包作为命名空间。66
67
```cangjie68
// a.cj69
package p170
public class C {}71
72
// b.cj73
package p274
public class C {}75
76
// main1.cj77
package pkga78
import p1.C79
import p2.C80
81
main() {82
let _ = C() // Error83
}84
85
// main2.cj86
package pkgb87
import p1.C as C188
import p2.C as C289
90
main() {91
let _ = C1() // OK92
let _ = C2() // OK93
}94
95
// main3.cj96
package pkgc97
import p198
import p299
100
main() {101
let _ = p1.C() // OK102
let _ = p2.C() // OK103
}104
```v1.1.0
Section Text
1
不同包的名字空间是分隔的,因此在不同的包之间可能存在同名的顶层声明。在导入不同包的同名顶层声明时,支持使用 `import packageName.name as newName` 的方式进行重命名来避免冲突。没有名字冲突的情况下仍然可以通过 `import as` 来重命名导入的内容。`import as` 具有如下规则:2
3
- 使用 `import as` 对导入的声明进行重命名后,当前包只能使用重命名后的新名字,原名无法使用。4
- 如果重命名后的名字与当前包顶层作用域的其他名字存在冲突,且这些名字对应的声明均为函数类型,则参与函数重载,否则报重定义的错误。5
- 支持 `import pkg as newPkgName` 的形式对包名进行重命名,以解决不同模块中同名包的命名冲突问题。6
<!-- compile.error -import3-->7
<!-- cfg="-p p1 --output-type=staticlib" -->8
9
```cangjie10
// a.cj11
package p112
public func f1() {}13
```14
15
<!-- compile.error -import3-->16
<!-- cfg="-p p2 --output-type=staticlib" -->17
18
```cangjie19
// d.cj20
package p221
public func f3() {}22
```23
24
<!-- compile.error -import3-->25
<!-- cfg="-p p1 --output-type=staticlib" -->26
27
```cangjie28
// b.cj29
package p130
public func f2() {}31
```32
33
<!-- compile.error -import3-->34
<!-- cfg="-p pkgc --output-type=staticlib" -->35
36
```cangjie37
// c.cj38
package pkgc39
public func f1() {}40
```41
42
<!-- compile.error -import3-->43
<!-- cfg="libp1.a libpkgc.a libp1.a" -->44
45
```cangjie46
// main.cj47
import p1 as A48
import p1 as B49
import p2.f3 as f // OK50
import pkgc.f1 as a51
import pkgc.f1 as b // OK52
53
func f(a: Int32) {}54
55
main() {56
A.f1() // OK, package name conflict is resolved by renaming package name.57
B.f2() // OK, package name conflict is resolved by renaming package name.58
p1.f1() // Error, the original package name cannot be used.59
a() // OK.60
b() // OK.61
pkgc.f1() // Error, the original name cannot be used.62
}63
```64
65
- 如果没有对导入的存在冲突的名字进行重命名,在 `import` 语句处不报错;在使用处,会因为无法导入唯一的名字而报错。这种情况可以通过 `import as` 定义别名或者 `import fullPackageName` 导入包作为命名空间。66
67
<!-- compile -import1 -->68
<!-- cfg="-p p1 --output-type=staticlib" -->69
70
```cangjie71
// a.cj72
package p173
public class C {}74
```75
76
<!-- compile -import1 -->77
<!-- cfg="-p p2 --output-type=staticlib" -->78
79
```cangjie80
// b.cj81
package p282
public class C {}83
```84
85
<!-- code_check_manual -->86
87
```cangjie88
// main1.cj89
package pkga90
import p1.C91
import p2.C92
93
main() {94
let _ = C() // Error95
}96
```97
98
<!-- compile -import1 -->99
<!-- cfg="-p pkgb libp1.a libp2.a" -->100
101
```cangjie102
// main2.cj103
package pkgb104
import p1.C as C1105
import p2.C as C2106
107
main() {108
let _ = C1() // OK109
let _ = C2() // OK110
}111
```112
113
<!-- compile -import1 -->114
<!-- cfg="-p pkgc libp1.a libp2.a" -->115
116
```cangjie117
// main3.cj118
package pkgc119
import p1120
import p2121
122
main() {123
let _ = p1.C() // OK124
let _ = p2.C() // OK125
}126
```modified重导出一个导入的名字textcode+4 lines
v1.0.5
Section Text
1
在功能繁多的大型项目的开发过程中,这样的场景是非常常见的:包 `p2` 大量地使用从包 `p1` 中导入的声明,当包 `p3` 导入包 `p2` 并使用其中的功能时,`p1` 中的声明同样需要对包 `p3` 可见。如果要求包 `p3` 自行导入 `p2` 中使用到的 `p1` 中的声明,这个过程将过于繁琐。因此希望能够在 `p2` 被导入时一并导入 `p2` 使用到的 `p1` 中的声明。2
3
在仓颉编程语言中,`import` 可以被 `private`、`internal`、`protected`、`public` 访问修饰符修饰。其中,被 `public`、`protected` 或者 `internal` 修饰的 `import` 可以把导入的成员重导出(如果这些导入的成员没有因为名称冲突或者被遮盖导致在本包中不可用)。其他包可以根据可见性直接导入并使用本包中用重导出的内容,无需从原包中导入这些内容。4
5
- `private import` 表示导入的内容仅当前文件内可访问,`private` 是 `import` 的默认修饰符,不写访问修饰符的 `import` 等价于 `private import`。6
- `internal import` 表示导入的内容在当前包及其子包(包括子包的子包)均可访问。非当前包访问需要显式 `import`。7
- `protected import` 表示导入的内容在当前 module 内都可访问。非当前包访问需要显式 `import`。8
- `public import` 表示导入的内容外部都可访问。非当前包访问需要显式 `import`。9
10
在下面的例子中,`b` 是 `a` 的子包,在 `a` 中通过 `public import` 重导出了 `b` 中定义的函数 `f`。11
12
13
14
15
需要注意的是,包不可以被重导出:如果被 `import` 导入的是包,那么该 `import` 不允许被 `public`、`protected` 或者 `internal` 修饰。16
17
<!-- compile.error -->Code 1 · cangjie
1
package a2
public import a.b.f3
4
public let x = 0Code 2 · cangjie
1
internal package a.b2
3
public func f() { 0 }Code 3 · cangjie
1
import a.f // OK2
let _ = f() // OKCode 4 · cangjie
1
public import a.b // Error, cannot re-export packagev1.1.0
Section Text
1
在功能繁多的大型项目的开发过程中,这样的场景是非常常见的:包 `p2` 大量地使用从包 `p1` 中导入的声明,当包 `p3` 导入包 `p2` 并使用其中的功能时,`p1` 中的声明同样需要对包 `p3` 可见。如果要求包 `p3` 自行导入 `p2` 中使用到的 `p1` 中的声明,这个过程将过于繁琐。因此希望能够在 `p2` 被导入时一并导入 `p2` 使用到的 `p1` 中的声明。2
3
在仓颉编程语言中,`import` 可以被 `private`、`internal`、`protected`、`public` 访问修饰符修饰。其中,被 `public`、`protected` 或者 `internal` 修饰的 `import` 可以把导入的成员重导出(如果这些导入的成员没有因为名称冲突或者被遮盖导致在本包中不可用)。其他包可以根据可见性直接导入并使用本包中用重导出的内容,无需从原包中导入这些内容。4
5
- `private import` 表示导入的内容仅当前文件内可访问,`private` 是 `import` 的默认修饰符,不写访问修饰符的 `import` 等价于 `private import`。6
- `internal import` 表示导入的内容在当前包及其子包(包括子包的子包)均可访问。非当前包访问需要显式 `import`。7
- `protected import` 表示导入的内容在当前 module 内都可访问。非当前包访问需要显式 `import`。8
- `public import` 表示导入的内容外部都可访问。非当前包访问需要显式 `import`。9
10
在下面的例子中,`b` 是 `a` 的子包,在 `a` 中通过 `public import` 重导出了 `b` 中定义的函数 `f`。11
12
<!-- compile -reimport1 -->13
<!-- cfg="-p a/b --output-type=staticlib" -->14
15
16
<!-- compile -reimport1 -->17
<!-- cfg="-p a --output-type=staticlib" -->18
19
20
<!-- compile -reimport1 -->21
<!-- cfg="liba.a liba.b.a" -->22
23
24
需要注意的是,包不可以被重导出:如果被 `import` 导入的是包,那么该 `import` 不允许被 `public`、`protected` 或者 `internal` 修饰。25
26
<!-- compile.error -->Code 1 · cangjie
1
internal package a.b2
3
public func f() { 0 }Code 2 · cangjie
1
package a2
public import a.b.f3
4
public let x = 0Code 3 · cangjie
1
import a.f // OK2
let _ = f() // OKCode 4 · cangjie
1
public import a.b // Error, cannot re-export package