Built-in Compilation Tags
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
中文
5 modified sections0 code block delta0 anchor delta
modified@FastNativetext+2 lines, -1 line
v1.0.5
Section Text
1
为了提升与 `C` 语言互操作的性能,仓颉提供 `@FastNative` 标记用于优化对 `C` 函数的调用。值得注意的是 `@FastNative` 只能用于 `foreign` 声明的函数。2
3
首先编译以下 C 语言程序得到动态库文件 `libcProg.so`,示例如下:4
5
6
仓颉文件 `main.cj`:7
8
9
具体的编译介绍,详情请参见[附录](../Appendix/compile_options.md#cjc-编译选项)。下面为该用例对应的编译命令:10
11
12
执行上述命令编译 `main.cj` 之后生成一个可执行文件 `main`,其执行结果如下:13
14
15
开发者在使用 `@FastNative` 修饰 `foreign` 函数时,应确保对应的 `C` 函数满足以下两点要求:16
17
1. 函数的整体执行时间不宜太长。例如:不允许函数内部存在很大的循环;不允许函数内部产生阻塞行为,例如:调用 `sleep`、`wait` 等函数。18
2. 函数内部不能调用仓颉方法。Code 1 · c
1
#include <stdio.h>2
3
char* foo()4
{5
static char str[] = "this is an example";6
return str;7
}Code 2 · cangjie
1
@FastNative2
foreign func foo(): CPointer<Int32>3
4
@FastNative5
foreign func printf(fmt: CPointer<Int32>, ...): Int326
7
main(): Int32 {8
unsafe{9
let str = foo()10
printf(str)11
}12
}Code 3 · shell
1
cjc -L . -lcProg ./main.cjCode 4 · text
1
this is an examplev1.1.0
Section Text
1
为了提升与 `C` 语言互操作的性能,仓颉提供 `@FastNative` 标记用于优化对 `C` 函数的调用。值得注意的是 `@FastNative` 只能用于 `foreign` 声明的函数。2
3
首先编译以下 C 语言程序得到动态库文件 `libcProg.so`,示例如下:4
5
6
仓颉文件 `main.cj`:7
8
<!-- code_no_check -->9
10
11
具体的编译介绍,详情请参见[附录](../Appendix/compile_options.md)。下面为该用例对应的编译命令:12
13
14
执行上述命令编译 `main.cj` 之后生成一个可执行文件 `main`,其执行结果如下:15
16
17
开发者在使用 `@FastNative` 修饰 `foreign` 函数时,应确保对应的 `C` 函数满足以下两点要求:18
19
1. 函数的整体执行时间不宜太长。例如:不允许函数内部存在很大的循环;不允许函数内部产生阻塞行为,例如:调用 `sleep`、`wait` 等函数。20
2. 函数内部不能调用仓颉方法。Code 1 · c
1
#include <stdio.h>2
3
char* foo()4
{5
static char str[] = "this is an example";6
return str;7
}Code 2 · cangjie
1
@FastNative2
foreign func foo(): CPointer<Int32>3
4
@FastNative5
foreign func printf(fmt: CPointer<Int32>, ...): Int326
7
main(): Int32 {8
unsafe{9
let str = foo()10
printf(str)11
}12
}Code 3 · shell
1
cjc -L . -lcProg ./main.cjCode 4 · text
1
this is an examplemodified@Frozentext+3 lines, -8 lines
v1.0.5
Section Text
1
`@Frozen` 标记可用于修饰函数和属性。如果确定某个函数、属性在将来的版本更新中不会去修改它的内部实现,那么可以使用 `@Frozen` 对其进行标记,该标记代表开发者对该函数/属性在未来版本演进的一种承诺。被 `@Frozen` 修饰的函数和属性,在后续的升级版本中,签名和函数体都不能发生任何变化。这意味着,前后两个代码版本,在相同编译器、相同编译选项的情况下,该函数或属性的生成产物完全一致。2
3
`@Frozen` 标记可被用于修饰:4
5
- 全局函数6
- 类、结构、接口、扩展、枚举中的函数7
- 类、接口、扩展中的属性8
9
`@Frozen` 标记不可被用于修饰:10
11
- 除了函数和属性以外的其他类型声明12
- 嵌套函数13
- 表达式14
15
使用示例如下:16
17
<!-- run -->Code 1 · cangjie
1
@Frozen2
public func test(): Unit {}3
4
public class testClass {5
@Frozen6
public func testFunc(): Unit {}7
8
@Frozen9
public prop testProp: Unit {10
get() {}11
}12
}v1.1.0
Section Text
1
`@Frozen` 标记可用于修饰函数和属性。如果确定某个函数、属性在将来的版本更新中不会去修改它的内部实现,那么可以使用 `@Frozen` 对其进行标记,该标记代表开发者对该函数/属性在未来版本演进的一种承诺。被 `@Frozen` 修饰的函数和属性,在后续的升级版本中,签名和函数体都不能发生任何变化。这意味着,前后两个代码版本,在相同编译器、相同编译选项的情况下,该函数或属性的生成产物完全一致。2
3
`@Frozen` 注解仅可用于修饰:4
5
- 除局部(嵌套)函数外的所有种类的函数定义,包括全局函数、成员函数、构造函数、主构造函数和析构函数。6
- 所有种类的成员属性定义。7
8
使用示例如下:9
10
<!-- run -->Code 1 · cangjie
1
@Frozen2
public func test(): Unit {}3
4
public class testClass {5
@Frozen6
public func testFunc(): Unit {}7
8
@Frozen9
public prop testProp: Unit {10
get() {}11
}12
}modified@Attributetextcode+4 lines
v1.0.5
Section Text
1
仓颉语言内部提供 `@Attribute` 标记,开发者通过内置的 `@Attribute` 来对某个声明设置属性值,从而达到标记声明的目的。属性值可以是 `identifier` 或者 `string`,下面是一个简单的例子,这段示例代码为变量 `cnt` 添加了一个 `identifier` 类型的属性 `State`,为变量 `bcnt` 添加了一个 `string` 类型的属性 `"Binding"`。2
3
4
同时,标准库 `std.ast` 包提供了 `getAttrs()` 方法用于获取节点的属性,以及 `hasAttr(attrs: String)` 方法用于判断当前节点是否具有某个属性,下面是一个具体的例子。5
6
宏定义如下:7
8
9
宏调用如下:Code 1 · cangjie
1
@Attribute[State] var cnt = 0 // identifier2
@Attribute["Binding"] var bcnt = 0 // stringCode 2 · cangjie
1
public macro Component(input: Tokens): Tokens {2
var varDecl = parseDecl(input)3
if (varDecl.hasAttr("State")) { // 如果该节点被标记了属性且值为 “State” 返回 true, 否则返回 false4
var attrs = varDecl.getAttrs() // 返回一组 Tokens5
println(attrs[0].value)6
}7
return input8
}Code 3 · cangjie
1
@Component(2
@Attribute[State] var cnt = 03
)v1.1.0
Section Text
1
仓颉语言内部提供 `@Attribute` 标记,开发者通过内置的 `@Attribute` 来对某个声明设置属性值,从而达到标记声明的目的。属性值可以是 `identifier` 或者 `string`,下面是一个简单的例子,这段示例代码为变量 `cnt` 添加了一个 `identifier` 类型的属性 `State`,为变量 `bcnt` 添加了一个 `string` 类型的属性 `"Binding"`。2
3
<!-- compile -->4
5
6
同时,标准库 `std.ast` 包提供了 `getAttrs()` 方法用于获取节点的属性,以及 `hasAttr(attrs: String)` 方法用于判断当前节点是否具有某个属性,下面是一个具体的例子。7
8
宏定义如下:9
10
<!-- run -macro0 -->11
<!-- cfg="--compile-macro" -->12
13
14
宏调用如下:15
16
<!-- run -macro0 -->17
<!-- cfg="--debug-macro" -->Code 1 · cangjie
1
@Attribute[State] var cnt = 0 // identifier2
@Attribute["Binding"] var bcnt = 0 // stringCode 2 · cangjie
1
macro package define2
3
public macro Component(input: Tokens): Tokens {4
var varDecl = parseDecl(input)5
if (varDecl.hasAttr("State")) { // 如果该节点被标记了属性且值为 "State",则返回 true,否则返回 false6
var attrs = varDecl.getAttrs() // 返回一组 Tokens7
println(attrs[0].value)8
}9
return input10
}Code 3 · cangjie
1
import define.Component2
3
@Component(4
@Attribute[State] var cnt = 05
)6
7
main() {}modified@Deprecatedtext+1 line
v1.0.5
Section Text
1
`@Deprecated` 表示此 API 已废弃,虽然暂时可用,但未来将被移除或更改,建议其他开发者不要调用此 API。例如:2
3
4
编译器编译时将提供告警信息:5
6
7
@Deprecated 自定义宏可以应用于以下声明:8
9
- 类、接口、结构体、枚举、枚举构造器10
- 顶级(全局)函数或变量11
- 静态或非静态的成员函数、成员变量、属性、属性设置器12
- 运算符函数13
- 扩展的成员函数、静态函数、属性或属性设置器14
- foreign 函数或声明在 foreign 块内的函数15
- 构造函数和主构造函数16
- 抽象的函数和属性17
- 类型别名(包括关联类型)18
- 函数具有默认参数的命名参数19
- const 变量和函数20
- 宏定义21
- 注解类Code 1 · cangjie
1
@Deprecated["用boo代替", since: "1.3.4"]2
func foo() {}3
4
main() {5
foo()6
}Code 2 · text
1
warning: function 'foo' is deprecated since 1.3.4. 用boo代替2
==> file.cj:5:5:3
|4
5 | foo()5
| ^^^ deprecated6
|7
# note: this warning can be suppressed by setting the compiler option `-Woff deprecated`8
9
1 warning generated, 1 warning printed.v1.1.0
Section Text
1
`@Deprecated` 表示此 API 已废弃,虽然暂时可用,但未来将被移除或更改,建议其他开发者不要调用此 API。例如:2
3
<!-- compile -->4
5
6
编译器编译时将提供告警信息:7
8
9
@Deprecated 自定义宏可以应用于以下声明:10
11
- 类、接口、结构体、枚举、枚举构造器12
- 顶级(全局)函数或变量13
- 静态或非静态的成员函数、成员变量、属性、属性设置器14
- 运算符函数15
- 扩展的成员函数、静态函数、属性或属性设置器16
- foreign 函数或声明在 foreign 块内的函数17
- 构造函数和主构造函数18
- 抽象的函数和属性19
- 类型别名(包括关联类型)20
- 函数具有默认参数的命名参数21
- const 变量和函数22
- 宏定义23
- 注解类Code 1 · cangjie
1
@Deprecated["用boo代替", since: "1.3.4"]2
func foo() {}3
4
main() {5
foo()6
}Code 2 · text
1
warning: function 'foo' is deprecated since 1.3.4. 用boo代替2
==> file.cj:5:5:3
|4
5 | foo()5
| ^^^ deprecated6
|7
# note: this warning can be suppressed by setting the compiler option `-Woff deprecated`8
9
1 warning generated, 1 warning printed.modified@Deprecated 参数text+1 line
v1.0.5
Section Text
1
- `message: String` - 描述声明为何废弃、如何迁移等。2
- `since!: ?String` - 废弃版本。3
- `strict!: Bool` - 默认值为 `false`,在被该标记修饰的 API 的调用处会触发警告。如果设置为 `true`,则会触发编译错误。Code 1 · cangjie
1
@Deprecated["Use Macro2", since: "1990", strict: true]2
public macro Macro(input: Tokens): Tokens {3
return input4
}v1.1.0
Section Text
1
- `message: String` - 描述声明为何废弃、如何迁移等。2
- `since!: ?String` - 废弃版本。3
- `strict!: Bool` - 默认值为 `false`,在被该标记修饰的 API 的调用处会触发警告。如果设置为 `true`,则会触发编译错误。4
5
<!-- compile.error -->Code 1 · cangjie
1
@Deprecated["Use Macro2", since: "1990", strict: true]2
public macro Macro(input: Tokens): Tokens {3
return input4
}