仓颉编程(1)环境配置变量
仓颉语言基本概况
一、仓颉语言简介
仓颉(Cangjie) 是 华为(Huawei)自研的新一代编程语言,于 2023 年华为开发者大会(HDC 2023)上首次公开。
它的名字来源于中国古代造字者“仓颉”,寓意为——“让开发者以更自然的方式与机器交流”。
仓颉主要面向:
- 全场景设备编程(手机、平板、IoT、车机等)
- 多端统一开发
- 高性能系统编程 + 安全性
- 与鸿蒙(HarmonyOS)深度集成
二、语言设计理念
目标 | 设计思想 | 对标语言 |
高性能 | 运行效率接近 C/C++ | Rust、C++ |
安全可靠 | 内存安全、类型安全、并发安全 | Rust、Go |
易用高效 | 更接近自然语义,简化语法 | Swift、Kotlin |
多范式融合 | 支持面向对象 + 函数式编程 | Scala、Dart |
多端统一 | 一套代码适配手机、车机、IoT、PC 等 | Kotlin Multiplatform、Flutter |
三、语言特性概览
1. 语法简洁、类型推导强
fn add(a: Int, b: Int) -> Int {return a + b
}fn main() {let x = 10let y = 20println(add(x, y))
}
仓颉语法风格融合了 Rust + Swift + Kotlin 的特征:
fn
定义函数;let
定义不可变变量;var
定义可变变量;- 括号、分号都可以省略;
- 支持 类型自动推导。
2. 内存与并发安全
仓颉在底层引入:
- 编译期所有权与生命周期检查(类似 Rust)
- 无锁并发模型
- 任务隔离机制(Task Isolation)
这意味着开发者在并发编程中几乎不用担心数据竞争、悬垂指针或 use-after-free 等错误。
3. 面向对象与函数式并存
class Person(name: String, age: Int) {fun greet() {println("Hi, I'm \(name), \(age) years old")}
}fn main() {let p = Person("Cangjie", 2023)p.greet()
}
同时支持:
- 类(class)与结构体(struct)
- 模式匹配(match)
- lambda 表达式
- 高阶函数(map/filter/reduce)
- 不可变集合
4. 模块与包管理(cjpm)
仓颉提供官方包管理器 cjpm(Cangjie Package Manager):
cjpm new hello
cjpm build
cjpm run
相当于 Rust 的 cargo
或 Node 的 npm
:
- 自动下载依赖;
- 支持版本控制;
- 支持模块化编译;
- 集成测试与发布。
5. 并发模型:Task + Channel
仓颉原生支持异步编程:
task asyncAdd(a: Int, b: Int) -> Int {return a + b
}fn main() {let result = asyncAdd(10, 20).awaitprintln(result)
}
可通过 task
创建异步任务,通过 await
等待结果;
内部实现是无锁的 轻量级任务调度器(协程模型)。
6. 强大的跨平台与编译特性
目标平台 | 输出形式 |
鸿蒙设备(OpenHarmony) | Ark Runtime 二进制 |
Windows / Linux / macOS | 原生可执行程序 |
Web(未来) | WebAssembly |
IoT / 嵌入式 | 精简版编译模式 |
这意味着未来可以:
一份仓颉代码 → 同时运行在手机、平板、车机、IoT 上。
四、仓颉的生态与工具链
工具 | 功能 | 备注 |
Cangjie SDK | 核心编译器、标准库、运行时 | 官方下载 |
cjpm | 包管理器 | 类似 Rust 的 Cargo |
JetBrains Cangjie 插件 | IDE 支持 | 类似 IntelliJ 插件 |
Ark Compiler | 底层运行时与优化引擎 | HarmonyOS 使用 |
Cangjie REPL | 交互式解释器(测试) | 命令行调试 |
五、典型语法特征总结
特性 | 示例 | 说明 |
条件语句 |
| 需要括号 |
匹配模式 |
| 类似 Rust |
循环语句 |
| 支持范围 |
错误处理 |
| 类似 Kotlin |
模块导入 |
| 简洁模块语法 |
泛型 |
| 类似 Rust/Swift |
六、与其他语言对比
特性 | 仓颉 | Rust | Kotlin | Go | Swift |
内存安全 | ✅ 编译期保证 | ✅ | ⚠️ JVM 管理 | ✅ GC | ✅ |
性能 | ✅ 接近 C++ | ✅ | ⚠️ 略低 | ⚠️ 中等 | ✅ |
多端统一 | ✅ HarmonyOS 支持 | ❌ | ✅ Android/JS | ⚠️ | ✅ Apple |
包管理 | ✅ cjpm | ✅ cargo | ✅ gradle | ✅ go mod | ✅ swiftpm |
并发模型 | ✅ Task+Channel | ✅ async/await | ✅ coroutine | ✅ goroutine | ✅ async |
企业生态 | 🚀 华为主推 | 社区驱动 | JetBrains | | Apple |
七、发展现状与未来方向
截至 2025 年:
- 仓颉语言主要用于 鸿蒙应用与系统开发;
- 官方正逐步开放 PC 端与命令行编程能力;
- 社区生态正在形成(GitHub 与 Gitee 上已有早期开源项目);
- 有望成为中国自研的首个 全栈统一编程语言生态。
未来方向包括:
- WebAssembly 编译支持;
- AI Native 编程接口(AI Model SDK);
- 安全内核与可信执行环境(TEE)编程;
- Cangjie → ArkTS 跨语言互操作。
仓颉语言环境配置
Windows 下SDK安装
在 Windows 平台上,仓颉为开发者提供了 exe
和 zip
两种格式的安装包,请前往仓颉官网,选择和下载适配平台架构的 Windows 版安装包。
- 如果选择
exe
格式的安装包(例如cangjie-sdk-windows-x64-x.y.z.exe
),请直接执行此文件,跟随安装向导点击操作,即可完成安装。 - 如果选择
zip
格式的安装包(例如cangjie-sdk-windows-x64-x.y.z.zip
),请将它解压到适当目录,在安装包中,仓颉为开发者提供了三种不同格式的安装脚本,分别是envsetup.bat
,envsetup.ps1
和envsetup.sh
,可以根据使用习惯及环境配置,选择一种执行:
-
- 若使用 Windows 命令提示符(CMD)环境,请执行:
path\to\cangjie\envsetup.bat
-
- 若使用 PowerShell 环境,请执行:
. path\to\cangjie\envsetup.ps1
-
- 若使用 MSYS shell、bash 等环境,请执行:
source path/to/cangjie/envsetup.sh
为了验证是否安装成功,请在以上命令环境中继续执行 cjc -v
命令,如果输出了仓颉编译器版本信息,表示已经成功安装了仓颉工具链。
值得注意的是,基于 zip 安装包和执行脚本的安装方式,类似于 Linux 平台,即 envsetup 脚本所配置的环境变量,只在当前命令行环境中有效,如果打开新的命令行窗口,需要重新执行 envsetup 脚本配置环境。此时,若想使仓颉工具链的环境变量配置在命令提示符或终端启动时自动生效,可以对系统进行如下配置:
- 若使用 bash 环境,可以根据如下步骤操作:
在 $HOME/.bashrc
初始化配置文件的最后加入以下命令($HOME
为当前用户目录的路径):
# 假设仓颉安装包解压在 /home/user/cangjie 中
source /home/user/cangjie/envsetup.sh # 即 envsetup.sh 的绝对路径
配置完成后 bash 启动即可直接使用仓颉编译工具链。
- 若使用 Windows 命令提示符(CMD)、PowerShell 或其他环境,可以根据如下步骤操作:
-
- 在 Windows 搜索框中,搜索 “查看高级系统设置” 并打开对应窗口;
- 单击 “环境变量” 按钮;
- 执行如下操作,配置 CANGJIE_HOME 变量:
-
-
- 在 “用户变量”(为当前用户进行配置)或 “系统变量”(为系统所有用户进行配置)区域中,查看是否已有 CANGJIE_HOME 环境变量。若没有,则单击 “新建” 按钮,并在 “变量名” 字段中输入
CANGJIE_HOME
;若有,则说明该环境可能已经进行过仓颉配置,如果想要继续为当前的仓颉版本进行配置并覆盖原配置,请点击 “编辑” 按钮,进入 “编辑系统变量” 窗口。 - 在 “变量值” 字段中输入仓颉安装包的解压路径,若原先已经存在路径,则使用新的路径覆盖原有的路径,例如仓颉安装包解压在
D:\cangjie
,则输入D:\cangjie
。 - 配置完成后, “编辑用户变量” 或 “编辑系统变量” 窗口中显示的变量名为
CANGJIE_HOME
、变量值为D:\cangjie
。确认路径正确配置后单击 “确定” 。
- 在 “用户变量”(为当前用户进行配置)或 “系统变量”(为系统所有用户进行配置)区域中,查看是否已有 CANGJIE_HOME 环境变量。若没有,则单击 “新建” 按钮,并在 “变量名” 字段中输入
-
-
- 执行如下操作,配置 Path 变量:
-
-
- 在 “用户变量”(为当前用户进行配置)或 “系统变量”(为系统所有用户进行配置)区域中,找到并选择 Path 变量,单击 “编辑” 按钮,进入 “编辑环境变量” 窗口。
- 分别单击 “新建” 按钮,并分别输入
%CANGJIE_HOME%\bin
、%CANGJIE_HOME%\tools\bin
、%CANGJIE_HOME%\tools\lib
、%CANGJIE_HOME%\runtime\lib\windows_x86_64_llvm
(%CANGJIE_HOME%
为仓颉安装包的解压路径)。例如,仓库安装包解压在D:\cangjie
,则新建的环境变量分别为:D:\cangjie\bin
、D:\cangjie\tools\bin
、D:\cangjie\tools\lib
、D:\cangjie\runtime\lib\windows_x86_64_llvm
。 - (仅适用于为当前用户设置)单击 “新建” 按钮,并输入当前用户目录路径,并在路径后面添加
.cjpm\bin
。例如用户路径在C:\Users\bob
,则输入C:\Users\bob\.cjpm\bin
。 - 配置完成后应能在 “编辑环境变量” 窗口中看到配置的路径如下所示。确认路径正确配置后单击 “确定” 。
-
D:\cangjie\bin
D:\cangjie\tools\bin
D:\cangjie\tools\lib
D:\cangjie\runtime\lib\windows_x86_64_llvm
C:\Users\bob\.cjpm\bin
-
- 单击 “确定” 按钮,退出 “环境变量” 窗口。
- 单击 “确定” 按钮,完成设置。
注意:
设置完成后可能需要重启命令行窗口或重启系统以让设置生效。
配置完成后 Windows 命令提示符(CMD)或 PowerShell 启动即可直接使用仓颉编译工具链。
变量
变量是任何编程语言当中相当于存储数据的”容器“,这些变量被开发者赋予数据之后,就存储着以待后续使用。创建变量时需要注意变量的三个核心要素:变量名、数据类型、变量值。
仓颉变量命名方法总览
分类 | 关键字 | 可变性 | 示例 |
不可变变量 |
| 不可修改 |
|
可变变量 |
| 可修改 |
|
常量(编译期) |
| 固定常量 |
|
引用变量 |
| 引用其他变量 |
|
惰性变量 |
| 延迟初始化 |
|
1. 不可变变量(let
)
let name = "Cangjie"
let age = 25
- 定义后不能被修改。
- 编译器自动推导类型(例如
String
,Int
)。 - 如果尝试重新赋值,会编译报错。
示例:
let x = 10
x = 20 // ❌ 错误:不可修改 let 变量(variable 'a' is immutable)
2. 可变变量(var
)
var counter = 0
counter += 1
println(counter) // 输出 1
- 可重复赋值;
- 类型仍由编译器推导;
- 适合计数器、循环变量、状态值等场景。
3. 常量(const
)
const
表示编译期常量:
const PI = 2.14159
const MAX_COUNT = 1000
特点:
- 必须在定义时初始化;
- 值在编译阶段确定;
- 不能依赖运行时结果或函数返回;
- 自动提升为静态常量。
错误示例:
const x = getTime() // ❌ 不允许:运行期计算
4. 引用变量(ref
)
仓颉支持“引用绑定”语义,类似 C++ 的 &
或 Rust 的引用:
var a = 10
ref b = a // b 引用 a
b = 20 // 改变 b 也会改变 a
println(a) // 输出 20
引用可用于:
- 避免复制大型数据;
- 在函数参数中进行引用传递;
- 实现共享可变状态。
5. 惰性变量(lazy
)
lazy
表示变量在首次使用时才会被求值:
lazy val config = loadConfigFile()
- 当程序未访问
config
时不会执行loadConfigFile()
; - 常用于性能优化或懒加载场景;
- 延迟变量必须保证线程安全(由语言自动保证)。
注释
类型 | 用法示例 | 用途 | 特征 |
单行注释 |
| 说明当前行或片段 | 快捷简洁 |
多行注释 |
| 屏蔽多行或大段内容 | 可嵌套 |
文档注释 |
或 | 自动生成 API 文档 | 支持 Markdown 格式 |
一、单行注释(Single-Line Comment)
最常见的注释方式,以 //
开头,直到行尾结束。
// 这是一个单行注释
let x = 10 // 声明变量 x 并赋值 10
特点:
- 不会被编译器执行;
- 可放在代码行前或行尾;
- 推荐用于解释简单逻辑或临时标记。
常见用法:
// TODO: 实现用户登录逻辑
// FIXME: 修复计数器溢出
// NOTE: 以下部分暂不启用
二、多行注释(Block Comment)
使用 /* ... */
包围的注释块,可跨越多行。
/*
这是一个多行注释
可以解释较长逻辑
或暂时屏蔽部分代码
*/
也可用于包裹代码段:
/*
fn debugTest() {println("调试中...")
}
*/
✅ 特点:
- 可跨多行;
- 常用于临时屏蔽代码或撰写大段说明;
- 在仓颉中支持嵌套使用(这是很多语言没有的特性)。
三、嵌套注释(Nested Block Comments)
仓颉支持嵌套式多行注释(类似 Rust、Swift):
/*
主注释块/* 内层注释块 */
结束
*/
特征:
- 编译器可正确匹配每一对
/*
与*/
; - 适合调试、分层屏蔽或逐级说明;
- 嵌套层数理论上不受限制(受编译器实现约束)。
注意:嵌套注释必须配对完整,否则编译器会报错:
error: unclosed comment block
四、文档注释(Documentation Comment)
仓颉支持 两种文档注释语法,用于生成开发文档(类似 Rustdoc / KDoc / Javadoc)。
形式 | 用法 | 示例 | 用途 |
单行文档注释 |
|
| 函数或类的说明 |
块状文档注释 |
|
| 支持 Markdown 格式说明 |
1. 单行文档注释(///
)
/// 计算两个整数的和
/// # 参数
/// - `a`: 第一个整数
/// - `b`: 第二个整数
/// # 返回值
/// 返回 a + b 的结果
fn add(a: Int, b: Int) -> Int {return a + b
}
特点:
- 紧贴函数、类、枚举、模块等定义上方;
- 自动被文档工具(如
cjdoc
或 IDE Doc Generator)识别; - 支持 Markdown 标记(如
#
标题、反引号代码块、列表等)。
2. 块状文档注释(/** ... */
)
适合写较长的说明或包含复杂格式的文档:
/*** 用户对象** ## 属性* - `name`: 用户名* - `age`: 年龄** ## 方法* - `greet()`: 打印问候语*/
class User(name: String, age: Int) {fun greet() {println("Hi, I'm \(name), \(age) years old")}
}
特点:
- 可换行;
- 每行可选择加
*
开头; - 支持嵌套 Markdown;
- 被 IDE 用于生成类/方法说明。
五、文档注释的 Markdown 支持
仓颉文档注释内支持以下格式:
Markdown 语法 | 示例 | 渲染效果 |
标题 |
| 二级标题 |
代码块 |
| 语法高亮 |
列表 |
| 无序列表 |
引用 |
| 高亮框 |
表格 | ` | 列1 |
示例:
/// # 示例
/// ```cj
/// let x = add(1, 2)
/// println(x)
/// ```
/// 输出:
/// ```
/// 3
/// ```
fn add(a: Int, b: Int) -> Int { a + b }
六、属性注释(Annotation Comment)
仓颉还支持一种“注释式元数据”,通常放在文档前,用 @
标识:
@deprecated("请使用 newAdd() 替代")
fn oldAdd(a: Int, b: Int) -> Int {return a + b
}
虽然这不属于传统意义的“注释”,但它与注释同样不会影响逻辑,用于提供编译器提示、警告或元信息。
这类注释常称为“属性注解(Attribute Annotation)”。
常见属性:
注解 | 含义 |
| 标记函数或类已废弃 |
| 标记实验性功能 |
| 表示测试函数 |
| 编译期内联建议 |
七、文档注释与工具链(cjdoc)
华为的 Cangjie SDK 自带 cjdoc
工具,可提取文档注释生成 HTML 或 Markdown 文档:
cjdoc build
会根据源文件中的:
/// 类 / 函数 / 模块说明
生成结构化开发文档,类似 Rust 的 cargo doc
。
总结表:仓颉所有注释写法对照
注释类型 | 语法 | 是否多行 | 可嵌套 | 主要用途 | 是否参与文档 |
单行注释 |
| 否 | 否 | 普通说明、TODO | 否 |
多行注释 |
| 是 | 支持 | 屏蔽代码、大段说明 | 否 |
嵌套注释 |
| 是 | 支持 | 调试临时关闭 | 否 |
单行文档注释 |
| 否 | 否 | 函数/类说明 | 是 |
块状文档注释 |
| 是 | 否 | 复杂文档说明 | 是 |
属性注释(元注释) |
| 否 | 否 | 元数据标记 | 是(特殊) |