华为自研的仓颉编程语言(英文名为Cangjie,简称“仓颉”或者“仓颉语言”),作为一款面向全场景应用开发的现代编程语言,通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的IDE工具链支持,为开发者打造友好开发体验和卓越程序性能。
仓颉特性
作为一门新进的编程语言,仓颉吸取了各大主流编程语言的优点,形成了自己具有特性。
- 高效编程:面向应用开发,编程语言应该能够易学易用,降低开发者入门门槛和开发过程中的心智负担,支持各种常见的开发范式和编程模式,让开发者简洁高效地表达各种业务逻辑。仓颉是一门多范式编程语言,支持函数式、命令式和面向对象等多种范式,包括值类型、类和接口、泛型、代数数据类型、模式匹配、以及高阶函数等特性。此外,仓颉还支持类型推断,能够减轻开发者类型标注的负担;通过一系列简明高效的语法,能够减少冗余书写、提升开发效率;语言内置的各种语法糖和宏(macro)的能力,支持开发者基于仓颉快速开发领域专用语言(DSL),构建领域抽象。
- 安全可靠:作为现代编程语言,仓颉追求编码即安全,通过静态类型系统和自动内存管理,确保程序的类型安全和null safety等内存安全;同时,仓颉还提供各种运行时检查,包括数组下标越界检查、类型转换检查、数值计算溢出检查、以及字符串编码合法性检查等,能够及时发现程序运行中的错误;此外,还通过代码扫描工具、混淆工具以及消毒器,进一步提供跨语言互操作安全和代码资产保护等支持。
- 轻松并发:并发和异步编程能够有效提高处理器利用率,并在交互式应用中确保程序的响应速度,是应用开发中必不可少的能力。仓颉语言实现了轻量化用户态线程和并发对象库,让高效并发变得轻松。仓颉语言采用用户态线程模型,每个仓颉线程都是极其轻量级的执行实体,拥有独立的执行上下文但共享内存。对开发者来说,用户态线程的使用和传统的系统线程的使用方式保持一致,没有带来额外负担;而从运行态视角看,线程的管理由运行时完成,不依赖操作系统的线程管理,因此线程的创建、调度和销毁等操作更加高效,且资源占用比系统线程更少。为了避免数据竞争,仓颉语言提供了并发对象库,并发对象的方法是线程安全的,因此在多线程中调用这些方法和串行编程没有区别,应用逻辑的开发者无需额外关心并发管理。对于一些核心库,仓颉还提供了无锁或者细粒度锁的算法实现,能够进一步减少线程的阻塞,提升并发度。
- 卓越性能:仓颉编译器及运行时,全方位针对编译进行了优化,包括编译器前端基于CHIR(Cangjie HighLevel IR)高层编译优化(比如语义感知的循环优化、语义感知的后端协同优化等),基于后端的编译优化(比如:SLP向量化、Intrinsic优化、InlineCache、过程间指针优化、Barrier优化等),基于运行时的优化(比如轻量锁、分布式标记、并发Tracing优化等),一系列的优化让仓颉充分发挥处理器能力,为应用提供卓越的性能支持。另外仓颉语言对运行时进行原生的轻量化设计,通过运行时的模块化分层设计,仓颉定义了公共对象模型和基础组件,统一实现内存管理、回栈、异常处理等核心能力,从而减少模块间的冗余设计,显著精简运行时体积。同时通过包的按需加载技术,减少仓颉应用启动的冗余包内存开销,因此对于资源敏感设备,占用资源更少,支持更友好。
除此之外,仓颉还支持面向应用开发的一系列工具链,包括语言服务(高亮、联想)、调试(跨语言调试、线程级可视化调试)、静态检查、性能分析、包管理、文档生成、Mock工具、测试框架、覆盖率工具、Fuzz工具以及智能辅助编程工具,进一步提升软件开发体验以及效率。
高效编程
仓颉是一个典型的多范式编程语言,对过程式编程、面向对象编程和函数式编程都提供了良好的支持。
1. 对于面向对象编程的支持
仓颉支持使用传统的类(class)和接口(interface)来实现面向对象范式编程。仓颉语言只允许单继承,每个类只能有一个父类,但可以实现多个接口。每个类都是Object的子类(直接子类或者间接子类)。此外,所有的仓颉类型(包括Object)都隐式的实现Any接口。
仓颉提供open修饰符,来控制一个类能不能被继承,或者一个对象成员函数能不能被子类重写(override)。
2. 对于函数式编程的支持
在仓颉里面,函数可以作为普通表达式使用,可以作为参数传递,作为函数返回值,被保存在其他数据结构中,或者赋值给一个变量使用。
3. 代数数据类型和模式匹配
代数数据类型是一种复合类型,指由其它数据类型组合而成的类型。两类常见的代数类型是积类型(如struct、tuple等)与和类型(如tagged union)。
模式匹配是一种测试表达式是否具有特定特征的方法,在仓颉中主要提供了match表达式来完成这个目标。对于给定的enum类型的表达式,使用match表达式来判断它是用哪个构造器构造的,并提取相应构造器的参数。除此enum模式以外,仓颉也提供了其它各种模式,如常量模式、绑定模式、类型模式等,以及各种模式的嵌套使用。
4. 泛型
仓颉支持泛型编程,诸如函数、struct、class、interface、extend都可以引入泛型变元以实现功能的泛型化。数组类型在仓颉中就是典型的泛型类型应用,其语法表示为Array<T>,其中T表示了元素的类型,可以被实例化为任何一个具体的类型,例如Array<Int>或Array<String>,甚至可以是嵌套数组Array<Array<Int>>,从而可以轻易地构造各种不同元素类型的数组。
除了类型外,仓颉还可以定义泛型函数。
5. 类型扩展
仓颉支持类型扩展特性,允许我们在不改变原有类型定义代码的情况下,为类型增加成员函数等功能。具体来说,
仓颉的类型扩展可以对已有的类型做如下几类扩展:
- 添加函数
- 添加属性
- 添加操作符重载
- 实现接口
6. 类型推断
仓颉作为现代编程语言,对类型推断也提供了良好的支持。
在仓颉中变量的定义可以根据初始化表达式的类型来推断其类型。除了变量以外,仓颉还额外支持了函数定义返回值类型的推断。在仓颉中,函数体的最后一个表达式会被视为这个函数的返回值。像变量一样,当函数定义省略了返回类型,函数就会通过返回值来推断返回类型。
安全可靠
编程语言的设计和实现,以及相应工具支持,对于程序质量和安全性有重要影响。
仓颉通过静态类型系统、动静态检查、自动内存管理、以及工具链来提升程序的安全性。具体包括:
- 静态类型和垃圾收集
- 空引用安全
- 值类型
- “不可变”优先
- 默认封闭
- try-with-resources
- 动态安全检查
- 混淆
轻松并发
仓颉语言为并发编程提供了一种简单灵活的方式,通过轻量化线程模型和高效易用的无锁并发对象让并发编程变得轻松,将高效并发处理的能力直接置于开发者的手中。
仓颉语言采用用户态线程模型,在该模型下,每个仓颉线程都是极其轻量级的执行实体,拥有独立的执行上下文但共享内存。该模型不仅简化了开发者编写并发代码的过程,还带来了显著的性能优势。
在多线程共享内存并发场景,仓颉提供了基于细粒度并发算法实现的并发对象,而用户通过调用并发对象的接口来操作多线程共享内存,从而实现以下特性。
- 为用户提供无锁编程体验:用户通过接口调用实现高效的共享内存并发访问。
- 为用户提供并发安全保障:仓颉并发对象的接口可保证无数据竞争,核心接口具有并发原子性。
- 提升性能:仓颉并发对象的设计使用细粒度并发算法。
- 保证并发原子性:仓颉并发对象的核心方法具有并发“原子性”,即从用户视角来看,该方法调用执行不会被其它线程打断。
卓越性能
仓颉语言通过值类型、多层级静态分析优化和超轻量运行时,在计算机语言基准测试游戏(The Computer Language Benchmarks Game)上,相比业界同类语言取得了较为明显的性能优势。如下图1-1所示的仓颉官方给出的性能测试数据,相比于Go、Java、Swift等主流语言,仓颉性能更优。
仓颉语言主要通过以下方式实现高性能。
- 仓颉编译采用模块化编译,编译流程间通过IR作为载体,不同编译优化之间,做到互相不影响。对于编译优化的适配,编译流程的调整,拥有更高的自由度。
- 仓颉语言使用静态编译手段,将仓颉程序、核心库代码等编译成机器代码,加速程序运行速度。
- 仓颉语言引入了值类型对象,值类型的局部变量在读写时无需垃圾回收机制(Garbage Collection,简称GC)相关屏障,在进行内存读写时,能够直接访问,无需考虑引用信息的变化。合理利用值类型语义,能有效加速程序运行。
- 仓颉提供全并发(fully concurrent)的内存标记整理GC算法作为其自动内存管理技术的底座,具有延迟极低、内存碎片率极低、内存利用率高的优势。
- 仓颉语言提供了超轻量化的运行时,不但自身的分发开销低,也帮助应用以极低的开销部署和运行。
参考引用
- 免费开源书《跟老卫学仓颉编程语言开发》https://github.com/waylau/cangjie-programming-language-tutorial
- HarmonyOS NEXT+AI大模型打造智能助手APP(仓颉版)
- 仓颉编程从入门到实践(北京大学出版社)
共同学习,写下你的评论
评论加载中...
作者其他优质文章

