Video2X 快速指南:免费的 AI 视频超分辨率与插帧,让 480p 老片直上 4K
【免费下载链接】CangjieCorpus
本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 RAG(检索增强生成)技术 的高质量知识基座,适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用,推动鸿蒙开发生态智能化升级!
仓颉编程语言是面向全场景应用开发的通用编程语言,兼顾开发效率与运行性能。本指南以 CangjieCorpus 语料库中"学习仓颉语言"主题导航为核心骨架,系统梳理仓颉从语法基础(标识符、程序结构、表达式、函数、数据类型)到进阶特性(枚举与模式匹配、泛型、类与接口、宏、反射注解、并发),再到工程实践(包管理、编译构建、条件编译)与跨语言互操作(C、ArkTS)的完整学习路径,并给出每一主题在仓库中的权威文档位置与可运行代码示例。读完本文,你将获得一张可直接照图索骥的仓颉语言学习地图,并能快速定位到对应源码与实战案例进行深入研读。
初识仓颉语言:语言定位与核心特性
在正式进入语法细节之前,先建立对仓颉语言的整体认知。根据初识仓颉语言的官方定义,仓颉是一门面向全场景应用开发的通用编程语言,其核心特性可归纳为:
- 多后端支持:支持 CJNative(编译为原生二进制代码,直接运行于操作系统)与 CJVM(编译为字节码,基于虚拟机运行)两种后端。当前 SDK 提供 CJNative 后端,CJVM 后端 SDK 敬请期待。
- 语法简明高效:提供插值字符串、主构造函数、Flow 表达式、
match、重导出等语法,用较少编码表达复杂逻辑。 - 多范式编程:融合函数式(高阶函数、代数数据类型、模式匹配、泛型)、面向对象(封装、接口、继承、子类型多态)与命令式(值类型、全局函数)编程范式。
- 类型安全:静态强类型语言,通过编译时类型检查尽早识别错误,同时编译器提供强大的类型推断能力,减少类型标注工作。
- 内存安全:支持自动内存管理,并在运行时进行数组下标越界检查、溢出检查等操作。
- 高效并发:提供用户态轻量化线程(原生协程)以及简单易用的并发编程机制。
- 兼容语言生态:支持与 C 等语言的互操作,采用声明式编程范式实现其他语言库的高效复用。
- 领域易扩展:提供基于词法宏的元编程能力,支持编译时变换代码,配合尾随
lambda、属性、操作符重载等特性,有利于内嵌式领域专用语言(EDSL)的构建。 - 助力 UI 开发:基于元编程和尾随
lambda等特性,可搭建声明式 UI 开发框架。 - 内置库功能丰富:涉及数据结构、常用算法、数学计算、正则匹配、系统交互、文件操作、网络通信、数据库访问、日志打印、解压缩、编解码、加解密和序列化等。
动手体验的最快方式是编写并运行第一个程序。在运行第一个仓颉程序中,新建 hello.cj 文件:
// hello.cj
main() {
println("你好,仓颉")
}
然后执行编译命令(Linux/macOS 平台;Windows 平台将输出名改为 hello.exe 即可):
cjc hello.cj -o hello
运行生成的可执行文件即可看到输出 你好,仓颉。注意仓颉支持 // 单行注释与 /* */ 多行注释,与 C/C++ 语法相同。
基本概念:标识符、程序结构与表达式
标识符
标识符用于为程序元素命名,分为普通标识符和原始标识符两类。仓颉采用 Unicode 标准 15.0.0,依据 XID_Start 与 XID_Continue 属性判定合法字符,因此中文可以直接用作标识符。
- 普通标识符:由
XID_Start字符开头后接任意长度XID_Continue字符;或由_开头后接至少一个XID_Continue字符。合法示例:abc、_abc、a1_b2_c3、仓颉、__こんにちは。不合法示例:3abc(数字不能开头)、_(_后至少需要一个字符)、while(关键字)。 - 原始标识符:在普通标识符或关键字首尾加反引号,用于将关键字当作标识符,如
`if`、`while`。
所有标识符被识别为 NFC(Normalization Form C)规范化后的形式,两个标识符若 NFC 后相等则视为相同。
程序结构
程序结构规定,仓颉源代码文件以 .cj 为扩展名。顶层作用域可以定义全局变量、全局函数和自定义类型(struct、class、enum、interface);编译为可执行文件时必须在顶层定义 main 作为程序入口。main 可以不写 func 修饰符,可带 Array<String> 参数,返回类型为整数类型或 Unit。
let a = 2023
func b() {}
struct C {}
class D {}
enum E { F | G }
main() {
println(a)
}
变量方面,仓颉变量定义形式为 修饰符 变量名: 变量类型 = 初始值,关键修饰符包括:
- 可变性修饰符:
let(不可变,只能赋值一次即初始化)与var(可变,可多次赋值),二者为必需修饰符。 const:编译期求值、运行时不可改变的常量,声明时必须初始化;const变量初始化后该实例所有成员均为const(深度 const)。- 可见性修饰符:
private、public等;静态性修饰符:static。
仓颉变量分为值类型变量(struct 及基础类型等,赋值产生拷贝)和引用类型变量(class、Array 等,赋值建立引用关系,多个变量可共享同一数据对象)。例如对 struct Copy 赋值 c2 = c1 后修改 c2.data 不影响 c1;对 class Share 赋值 s2 = s1 后修改 s2.data 会连带影响 s1。这一点在阅读数组类型时同样重要——Array 虽是 struct 类型,但其内部持有元素引用,所有引用共享元素数据。
作用域由大括号 {} 构造,嵌套作用域遵循"内层可访问外层绑定、内层定义可遮盖外层同名定义"的规则;顶层作用域级别最低。注意仓颉不允许使用单独的大括号,大括号必须依附于 if、match、函数体、类体等语法结构。
表达式
表达式定义"凡可求值的语言元素都是表达式",因此除算术表达式外,条件表达式、循环表达式、try 表达式等均可求值并作为值使用。
if表达式:if (条件) {分支 1} else {分支 2},条件是布尔类型表达式或let pattern语法糖。仓颉是强类型语言,if条件不能使用整数或浮点数(与 C 语言以非零为真的规则不同)。含else分支的if表达式求值时,其类型为各分支的最小公共父类型;未求值时类型为Unit。let pattern:构成为let pattern <- expression,可在if条件中通过逻辑与(&&)或逻辑或(||)组合,例如if (let Some(b) <- a && let Some(f) <- d)。while与do-while表达式:均为布尔条件驱动循环,类型为Unit。for-in表达式:遍历扩展了Iterable<T>接口的类型实例(内置区间和数组已实现)。迭代变量不可修改;可用通配符_代替迭代变量以避免 unused variable 告警;支持where条件过滤,如for (i in 0..8 where i % 2 == 1)。break与continue表达式:类型均为Nothing,用于终止循环或跳过本轮。
关于"代码块"的求值规则:代码块的值与类型等于最后一个表达式的值与类型;空代码块类型为 Unit。
基础数据类型:整数、浮点、布尔、字符、字符串、元组、数组、区间与特殊类型
基础数据类型是仓颉语法的基石,各类型详解可参见 basic_data_type 目录:
- 基本操作符:各类操作符及优先级总览,详细优先级表见附录操作符。
- 整数类型:有符号(
Int8/Int16/Int32/Int64/IntNative)与无符号(UInt8/UInt16/UInt32/UInt64/UIntNative)。N位有符号整数范围-2^(N-1) ~ 2^(N-1)-1,无符号范围0 ~ 2^N-1。在Int64适合时首选Int64(整数字面量在无上下文时默认推断为Int64)。字面量支持0b/0B(二进制)、0o/0O(八进制)、十进制、0x/0X(十六进制),可用_作分隔符,并支持i8/u8/i16/u16/i32/u32/i64/u64后缀明确类型。还支持字符字节字面量(如b'x'为UInt8类型 120),以及算术、位、关系、自增自减、复合赋值等操作符。 - 浮点类型:
Float32与Float64,支持科学计数法等字面量形式。 - 布尔类型:
Bool类型,取值true/false,支持逻辑与(&&)、逻辑或(||)、逻辑非(!)等操作。 - 字符类型:
Rune表示 Unicode 字符,字符字面量以r开头(如r'甲'),详见字符类型字面量章节。 - 字符串类型:
String类型由 Unicode 字符组合而成。字面量分三类:单行(单引号/双引号)、多行("""/''')、多行原始字符串(#""#形式,转义规则不适用)。插值字符串用${}包裹表达式,如"There are ${count * count} ${fruit}",可用于避免字符串拼接。字符串支持关系比较、+拼接,以及contains、split等常见操作(完整 API 见 extra/String.md)。 - 元组类型:将多个值组合为单一复合值,可用于
for-in遍历时解构序列元素。 - 数组类型:
Array<T>是单一元素类型的有序序列。支持字面量初始化([1, 2, 3])、构造函数初始化(Array<Int64>(3, repeat: 0)、Array<Int64>(3, {i => i + 1}))。通过下标访问(类型必须为Int64,越界时编译器可查则报编译错误,否则运行时抛异常),支持 Range 切片(arr1[0..5]、arr1[..3]、arr1[2..])。Array 长度不可变、不提供增删元素成员函数,但可修改已有元素。此外仓颉还引入值类型数组VArray<T, $N>,可减少堆上内存分配与 GC 压力,但传递/赋值时会产生拷贝开销,不建议在性能敏感场景使用较大长度VArray;VArray还用于仓颉与 C 数组的映射(见 cangjie-c.md)。 - 区间类型:
Range支持..(含首不含尾)与..=(含首含尾)两种形式,可直接用于for-in遍历(如for (i in 1..=100)求 1 到 100 之和)。 - Unit 类型:空类型,值为
(),类似其他语言的void,用于表示无意义返回值。 - Nothing 类型:所有类型的子类型,
break/continue/return等控制转移表达式的类型均为Nothing。
函数:定义、调用、Lambda、闭包、重载与操作符重载
函数以关键字 func 开头,依次为函数名、参数列表、可选返回值类型(冒号分隔)、函数体。
定义函数
定义函数中,参数分为非命名参数(p: T)与命名参数(p!: T,调用时需给定参数名);只能为命名参数设置默认值(p!: T = e),且非命名参数必须定义在命名参数之前。函数参数均为不可变变量,函数体内不能赋值。返回值类型可显式声明也可由编译器根据函数体和 return 表达式推导;指定 Unit 时编译器会在所有可能返回处自动插入 return ()。return 表达式类型为 Nothing。函数体的类型为最后一项的类型(表达式为表达式类型,变量定义/函数声明/空体为 Unit)。
调用函数、函数类型与嵌套函数
Lambda 表达式与闭包
Lambda 表达式语法为 { p1: T1, ..., pn: Tn => expressions | declarations }。无论有无参数,=> 都不可省略(尾随 lambda 除外)。参数类型可缺省,由上下文推断(赋值给变量时按变量类型推断,作实参时按形参类型推断);不支持声明返回类型,从上下文或表达式体推导。Lambda 支持立即调用:let r1 = { a: Int64, b: Int64 => a + b }(1, 2),也可赋值给变量后调用。仓颉的函数调用语法糖中包括尾随 lambda,使得 f2 { println("World") } 可省略 =>。闭包在函数调用语法糖基础上进一步讲解捕获外部变量的行为。
函数重载与操作符重载
函数重载允许多个同名函数通过参数类型/数量区分;操作符重载允许为自定义类型定义操作符行为(操作符与操作符函数的对应关系见附录操作符函数)。
const 函数与常量求值
const 函数和常量求值讲解 const 函数在编译期完成求值的能力,与程序结构中 const 变量配合,可在编译期计算常量表达式。
结构类型(struct)
struct 是仓颉的值类型。三篇文档构成完整脉络:
- 定义 struct 类型:成员变量、成员函数及访问修饰符的定义规则。
- 创建 struct 实例:构造函数与实例化方式。
- mut 函数:
mut修饰的成员函数可修改实例成员变量,是值类型可变性的关键机制。
注意 struct 是值类型,赋值/传参时产生拷贝,与 class(引用类型)行为不同;struct 之间不能继承。
枚举类型与模式匹配
枚举类型
枚举类型可理解为函数式语言中的代数数据类型(ADT)。以 enum 关键字定义,构造器(constructor)之间用 | 分隔:
enum RGBColor {
| Red(UInt8) | Green(UInt8) | Blue(UInt8)
}
- 支持同名构造器重载(参数个数不同);每个 enum 至少有一个有名字的构造器。
- 支持
...无名字构造器形成non-exhaustive enum,此时匹配需使用通配符_或绑定模式。 - 支持递归定义(如表达式树
Expr的Add(Expr, Expr))。 - enum 只能定义在顶层作用域;
enum值通过类型名.构造器或直接使用构造器构造,名字冲突时必须加类型名。
Option 类型
Option 类型是预定义的泛型 enum:
enum Option<T> {
| Some(T)
| None
}
它包含 Some(有值)和 None(无值)两个构造器,用于表示"可能有值也可能没有值"的场景。Option<T> 有简写 ?T(?Int64 等价于 Option<Int64>)。当上下文明确需要 Option<T> 时可直接传 T 值(编译器用 Some 封装);无上下文时构造 None 需使用 None<T> 语法。
模式概述与 match 表达式
模式概述系统介绍常量模式、通配符模式、绑定模式、enum 模式等各类模式;Refutability 讨论模式的可反驳性(refutable/irrefutable)。
match 表达式支持含匹配值与不含匹配值两种形式。含匹配值形式以 case 模式 => 操作 组织分支,支持 pattern guard(where cond)和 | 连接多个模式:
let c = RGBColor.Green(-100)
let cs = match (c) {
case Red(r) where r < 0 => "Red = 0"
case Red(r) => "Red = ${r}"
case Green(g) where g < 0 => "Green = 0"
case Green(g) => "Green = ${g}"
case Blue(b) where b < 0 => "Blue = 0"
case Blue(b) => "Blue = ${b}"
}
match 要求穷尽性:所有 case 覆盖范围的并集必须包含待匹配值的所有可能取值,否则编译报错;常用最后一个 case _ 通配分支保证穷尽。无匹配值形式则在 case 后直接放 Bool 表达式。match 表达式的类型为各分支最小公共父类型;值未被使用时类型为 Unit。其他使用模式的地方(如变量定义处解构)见其他。
类和接口:面向对象编程
类是面向对象的核心。class 是引用类型,与 struct(值类型)行为不同,且支持继承。
-
定义:
class定义体含成员变量(实例/静态)、静态初始化器(static init)、构造函数、成员函数、操作符函数。class只能定义在顶层作用域。 -
构造函数:普通构造函数以
init开头;主构造函数名字与类名相同,其成员变量形参(let/var前缀)同时具有定义成员变量和构造函数参数的功能,可大幅简化类定义:class Rectangle { public Rectangle(let width: Int64, let height: Int64) {} }创建实例时按"初始化有缺省值的变量 → 调用父类无参构造(如未显式调用)→ 执行构造体"的顺序执行。
-
终结器:
~init在实例被 GC 回收时调用,用于释放系统资源,但有严格限制(无参数、类不可open、触发时机不确定、执行线程不确定、依赖终结器的同步行为属于未定义行为等)。 -
继承:非抽象类需用
open修饰才可被继承,子类用<:指定父类;单继承,所有类的最终父类为Object。子类对象可赋给父类变量,反之不行。覆盖父类成员函数用override,重定义父类静态函数用redef;覆盖基于运行时类型动态派发。 -
访问修饰符:
private(类内可见)、internal(当前包及子包可见,缺省值)、protected(当前模块及子类可见)、public(模块内外可见)。 -
This 类型:
This占位符代指当前类类型,作为实例成员函数返回类型时会被识别为子类类型,支持流畅的链式设计。
接口定义抽象行为契约,类可实现多个接口;属性讲解成员属性的定义与访问控制;子类型关系系统阐述子类型判定规则;类型转换覆盖数值类型间转换、as 转换与向下转型等规则。
泛型
泛型概述定义参数化类型的关键术语:类型形参(声明时未知的类型,如 List<T> 的 T)、类型变元(声明体中对形参的引用)、类型实参(使用处指定的具体类型,如 List<Int64> 的 Int64)、类型构造器。在仓颉中,function、class、interface、struct、enum 均可声明泛型:
class List<T> {
var elem: Option<T> = None
var tail: Option<List<T>> = None
}
泛型专题共 9 篇文档:泛型函数、泛型接口、泛型类、泛型结构体、泛型枚举、泛型类型的子类型关系、类型别名(type 关键字)、泛型约束(where T <: SomeType 形式)。泛型约束在 C 互操作中同样常见,如 where T <: CType。
扩展机制
扩展概述引入仓颉的扩展能力,允许为已有类型补充成员。三篇文档构成完整体系:
Collection 类型:ArrayList、HashSet、HashMap 与迭代
基础 Collection 类型概述给出四类常用容器的选型建议与特性对比:
| 类型名称 | 元素可变 | 增删元素 | 元素唯一性 | 有序序列 |
|---|---|---|---|---|
Array<T> | Y | N | N | Y |
ArrayList<T> | Y | Y | N | Y |
HashSet<T> | N | Y | Y | N |
HashMap<K, V> | K: N, V: Y | Y | K: Y, V: N | N |
- Array:不需要增删元素但需要修改元素的场景。
- ArrayList:需要频繁增删查改元素。
- HashSet:希望每个元素唯一。
- HashMap:存储键值映射关系。
- Iterable 和 Collections:迭代器接口与遍历机制,
for-in的底层依据。
标准库 collection 包的完整 API 与实战示例可进一步参阅 collection_package_overview 及其 samples(如 sample_arraylist_add、sample_hashmap_add_remove_clear 等)。
包:组织、导入与程序入口
随着项目规模扩大,需要将源代码按功能分组管理。包的概述明确两个关键概念:
- 包是编译的最小单元,每个包可单独输出 AST 文件、静态库、动态库等产物;同一包内不允许同名顶层定义(函数重载除外),一个包可含多个源文件。
- 模块是若干包的集合,是第三方开发者发布的最小单元;程序入口只能位于模块根目录,顶层最多一个
main。
包的声明讲解 package 声明语法;顶层声明的可见性规定包内/包间访问规则。
包的导入核心语法为 import fullPackageName.itemName,支持:
- 批量导入:
import fullPackageName.{item1, item2}与通配导入import packageName.*。 - 重导出:
import可被private(默认)、internal、protected、public修饰,public/protected/internal import可将导入成员重导出给其他包使用;包本身不可被重导出。 import as重命名:解决不同包同名声明冲突,如import p1.C as C1、import p1 as A;重命名后原名不可用。- 约束:禁止导入当前源文件所在包的声明,禁止包间循环依赖,只允许导入当前文件可见的顶层声明。
- 隐式导入 core 包:
String、Range等类型可直接使用,是因为编译器自动隐式导入core包中所有public声明。
程序入口规定:可执行编译方式下编译器只在源文件根目录顶层查找 main;main 不可被访问修饰符修饰,可无参数或参数为 Array<String>,返回 Unit 或整数类型。无参数 main 示例:
main(): Int64 {
return 0
}
带参数示例:
main(args: Array<String>): Unit {
for (arg in args) {
println(arg)
}
}
编译后执行 ./main Hello, World 将逐行打印 Hello, 与 World。若 main 返回 String、参数非 Array<String> 或存在多个 main,均编译报错。
异常处理
定义异常区分两类异常基类:
Error:运行时系统内部错误与资源耗尽错误,应用程序不应抛出,出现时尽量安全终止程序;不可继承。Exception:程序运行时逻辑错误或 IO 错误导致的异常(如数组越界、打开不存在的文件),需在程序中捕获处理;可通过继承自定义。
Exception 的主要成员包括构造函数 init()/init(message: String)、属性 message、函数 toString()、getClassName()、printStackTrace()。
throw 和处理异常以 throw 抛出异常(throw 后表达式必须是 Exception 子类型,Error 不可手动 throw),以 try 表达式捕获处理:
- 普通 try 表达式:由 try 块、catch 块(零个或多个)、finally 块(无 catch 时必须有 finally)组成。
catchPattern通过模式匹配捕获异常,支持类型模式(e: ExceptionClass,可用|连接多个异常类,此时被捕获异常类型为各类型最小公共父类)和通配符模式(_,等价于e: Exception)。 - try-with-resources 表达式:用于自动释放非内存资源,
try (r = ResourceType(...))形式,资源类型必须实现Resource接口(isClosed(): Bool与close(): Unit)。catch/finally 可选,表达式类型为Unit。
异常处理专题还包含常见运行时异常(如 ArithmeticException、NegativeArraySizeException、OverflowException、IllegalArgumentException 等)与使用 Option(以 Option 类型替代异常处理的可空值场景)。
并发编程
并发概述介绍仓颉采用抢占式线程模型,区分语言线程与 native 线程:
- 仓颉线程:用户态轻量级线程,采用
M:N线程模型(M 个语言线程在 N 个 native 线程上调度),支持抢占且比操作系统线程更轻量。 - native 线程:语言线程的实现载体(一般为操作系统线程)。
大多数场景下开发者只需面向仓颉线程编程,但跨语言编程时需谨慎调用可能阻塞的 foreign 函数(如 IO 系统调用),否则会阻塞 native 线程、降低吞吐量。
创建线程使用 spawn 关键字并传递无形参 lambda:
main(): Int64 {
spawn { =>
println("New thread before sleeping")
sleep(100 * Duration.millisecond)
println("New thread after sleeping")
}
println("Main thread")
return 0
}
新线程会在主线程结束时一起停止。线程睡眠指定时长 sleep 详解 sleep() 的 Duration 用法。访问线程介绍线程句柄与状态访问;终止线程讲解线程终止机制;同步机制覆盖互斥锁等并发同步原语,标准库 sync 包 API 见 sync_package_overview。
基础 I/O 与网络编程
相关标准库实战示例见 io_samples(如 buffered_input_stream、string_reader)与 console_package_overview。
网络编程专题四篇:网络编程概述、Socket 编程(TCP/UDP/UNIX,见 net_samples)、HTTP 编程、WebSocket 编程。
宏:基于词法宏的元编程
宏的简介将宏定义为"输入和输出都是程序本身"的特殊函数,调用时使用 @ 加宏名称。一个经典例子是打印表达式值的 @dprint 宏:
macro package define
import std.ast.*
public macro dprint(input: Tokens): Tokens {
let inputStr = input.toString()
let result = quote(
print($(inputStr) + " = ")
println($(input)))
return result
}
关键要点:
- 宏必须声明在独立包中,使用
macro package声明;实现宏所需类型(Tokens、语法节点)位于标准库ast包,故需import std.ast.*。 quote表达式用于构造Tokens,插值$(...)可将表达式/值转换为Tokens插入。- 编译命令为
cjc define/*.cj --compile-macro后cjc main.cj -o main。
宏专题完整链路:Tokens 相关类型和 quote 表达式、语法节点、宏的实现、编译、报错与调试、宏包定义和导入、内置编译标记、实用案例。注意原导航文档中"语法节点"与"实用案例"的目标文件名在仓库中实际为 sytax_node.md 与 pratical_case.md。
反射和注解
- 动态特性:运行时类型信息与动态调用能力,对应标准库 reflect 包,实战示例见 typeInfo、memberInfo、annotation 等。
- 注解:注解定义与使用,是元数据与互操作声明的基础。
跨语言互操作:仓颉-C 与仓颉-ArkTS
仓颉与 C 互操作
仓颉-C 互操作是兼容既有生态的关键能力,支持双向调用。核心机制包括:
foreign关键字:声明 C 侧函数,只能有声明不能有实现;参数和返回类型须符合 C/仓颉类型映射;调用需在unsafe块中。@C修饰foreign时可省略。CFunc:可被 C 调用的函数(@C修饰的 foreign 函数、@C修饰的仓颉函数、CFunc类型的 lambda——不能捕获变量),对应 C 函数指针。inout参数:按引用传值,类型为CPointer<T>;仅可用于CFunc调用处,不能来源于class实例成员变量。unsafe:用于标识跨 C 调用的不安全行为,可修饰函数、表达式或作用域。- 调用约定
@CallingConv:支持CDECL(默认)与STDCALL。 - 类型映射:基础类型(
Int64↔int64_t等,IntNative↔ssize_t)、结构体(@C修饰的struct)、指针(CPointer<T>)、数组(VArray<T, $N>,不支持 C 柔性数组映射)、字符串(CString,通过LibC.mallocCString创建、用完需释放)。 sizeOf/alignOf:获取 C 互操作类型的内存占用与对齐字节数。CType接口:所有 C 互操作支持类型的父类型,用于泛型约束。- 编译选项:
--library-path/-L指定库搜索目录,--library/-l指定链接库。完整示例(C 侧drawPicture与仓颉侧Point/Cube结构体交互)以cjc -L . -l draw ./main.cj编译,运行需LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main。
仓颉与 ArkTS 互操作(OpenHarmony 场景)
在 OpenHarmony 应用中,仓颉与 ArkTS 的混合开发是核心实践场景,相关文档位于 ohos/zh-cn/application-dev/learn-cj/FFI,入门路径为:
- 构建第一个仓颉与 ArkTS 混合应用:在 DevEco Studio 中选择 [Cangjie] Hybrid Ability 模板创建混合工程,理解
entry/src/main/cangjie(仓颉源码)与entry/src/main/ets(ArkTS 源码)的目录分工。仓颉页面以组件形式嵌入 ArkTS 页面(通过CJHybridComponent接口,需指定library与component名称),页面路由通过router实现,且仓颉与 ArkTS 的 router 不互通,需通过声明式互操作宏(@Interop[ArkTS])将 ArkTS 侧路由函数注册给仓颉调用。 - 在已有 ArkTS 工程中增量使用仓颉:存量工程增量接入。
- 在仓颉代码里导入 ArkTS 模块:仓颉侧导入 ArkTS 模块。
进阶专题包括:概述、场景、互操作用法(声明式互操作宏、互操作库、ArkTS 侧使用互操作代码、仓颉侧调用互操作代码)、互操作使用案例(仓颉访问 ArkTS 数据、ArkTS 访问仓颉数据、仓颉多线程中使用互操作)、辅助库与开发规范。
编译和构建:cjc、cjpm 与条件编译
cjc 编译器
cjc 使用介绍编译命令基本用法,命令形式为 cjc [option] file...。cjc 会自动完成前端、后端编译与链接;cjc-frontend 仅进行前端编译至 LLVM IR,编译流程在前端结束中止,除编译器开发者外应优先使用 cjc。对 hello.cj 直接执行 cjc hello.cj 会在工作目录生成可执行文件 main(默认行为);可通过编译选项控制整包编译或指定输出文件名。全部编译选项详见 cjc 编译选项。
cjpm 包管理
CJPM(Cangjie Package Manager)是仓颉官方包管理工具,核心子命令包括:
| 子命令 | 说明 |
|---|---|
init | 初始化新仓颉模块(创建 cjpm.toml 与 src/main.cj) |
check | 检查依赖 |
update | 更新 cjpm.lock |
tree | 显示源码依赖树 |
build | 编译当前模块(先检查依赖,再调用 cjc;-V 打印全部编译过程命令) |
run | 编译并运行可执行产物 |
test / bench | 本地包或模块单测 / 基准测试 |
clean | 清理 target 目录 |
install / uninstall | 安装 / 卸载仓颉二进制 |
cjpm.toml 配置文件的关键字段:
[package]:cjc-version(所需 cjc 最低版本,必需)、name(模块名及 root 包名,必需)、version(必需)、output-type(输出类型,如executable,必需)、compile-option/override-compile-option/link-option(额外编译/链接选项)、src-dir/target-dir、package-configuration。[workspace]:members(成员模块列表,必需)、build-members/test-members及全局编译选项,与[package]不能同时存在。[dependencies]/[test-dependencies]/[script-dependencies]/[replace]:以git或path形式声明源码依赖。[ffi.c]:导入 C 语言库依赖。[profile]:build/test/bench 命令剖面配置。[target.xxx]:按后端和平台隔离的编译选项与依赖(含bin-dependencies二进制库依赖,支持目录与单文件两种形式)。
条件编译
条件编译使用内置编译标记 @When,编译条件用 [] 括起,可作用于导入节点和除 package 外的声明节点。基本用法:
@When[os == "Linux"]
class mc{}
main(): Int64 {
var a = mc()
return 0
}
内置编译条件变量包括:
os:目标平台操作系统,支持Windows、Linux、macOS,可用==/!=。backend:后端类型,支持cjnative、cjvm。arch:处理器架构,支持x86_64、aarch64。cjc_version:编译器版本,支持==/!=/>/</>=/<=,按补位(补齐 2 位)比较。debug:是否开启-g调试选项,仅支持!。test:是否启用--test单测选项,仅支持!。
自定义条件变量需通过 --cfg 编译选项(键值对形式,如 cjc --cfg "feature = lion, platform = dsp" source.cj)或 cfg.toml 配置文件(--cfg "./cfg" 指定搜索路径,文件内每行一个 键 = "值")定义。支持逻辑运算符组合多条件与括号明确优先级,例如:
@When[(test || feature == "lion") && !debug]
func fee() {
println("feature lion")
}
注意仓颉不支持条件编译嵌套;宏展开生成的代码中含有 @When[...] 会编译报错。
附录:编译选项、关键字、操作符与 TokenKind
学习导航的附录部分提供语法速查资料:
- cjc 编译选项:完整编译选项参考,如
-o(输出名)、-p/--package(指定包目录)、-g(调试模式)、--cfg(条件编译配置)、--test(单测)、-L/-l(链接库)、--compile-macro(宏编译)、--output-type(输出类型)等。 - 关键字:仓颉全部关键字清单,也是判断原始标识符用法的依据。
- 操作符:全部操作符及其优先级表。
- 操作符函数:操作符与可重载函数的对应关系。
- TokenKind 类型:词法 Token 类型枚举,宏开发与语法分析的基础。
学习路径总结
综合以上内容,仓颉语言的学习可按如下路线推进:
- 入门:阅读初识仓颉语言与运行第一个仓颉程序,建立语言整体认知并跑通编译运行链路。
- 基础语法:依次掌握基本概念(标识符、程序结构、表达式、函数)与基础数据类型。
- 进阶语言特性:函数专题 → 结构类型 → 枚举与模式匹配 → 类与接口 → 泛型 → 扩展,逐步构建多范式编程能力。
- 工程能力:Collection 容器选型 → 包组织与导入 → 异常处理 → 并发编程 → I/O 与网络。
- 元编程与互操作:宏、反射注解、仓颉-C 互操作;在 OpenHarmony 场景下进阶仓颉-ArkTS 混合开发。
- 编译构建:掌握
cjc/cjpm/条件编译,并随时查阅附录速查资料。
每一专题在 CangjieCorpus 仓库中均有对应文档与可验证代码示例(含编译错误示例以强化边界认知),标准库 API 与 samples 见 libs/std 各包目录,OpenHarmony 应用开发体系见 ohos/zh-cn/application-dev,可结合本路线图按需深入研读。
【免费下载链接】CangjieCorpus
本仓库为仓颉编程语言语料库,聚焦 仓颉编程语言 核心知识体系,整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源,经结构化处理与专业标注,构建为支持 RAG(检索增强生成)技术 的高质量知识基座,适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用,推动鸿蒙开发生态智能化升级!
更多推荐
所有评论(0)