在 6.21 召开的华为开发者大会(HDC2024)上,华为自研的国产编程语言“仓颉”终于对外正式发布了!
随着万物互联以及智能时代的到来,软件的形态将发生巨大的变化。一方面,移动应用和移动互联网领域仍然强力驱动人机交互、设备协同、智能化、安全性等方向的创新,另一方面人工智能也同样驱动软件朝智能化、端边云协同等方向演进。新技术、新场景下应用软件的开发对编程语言提出了新的诉求和挑战。
特性篇
随着万物互联以及智能时代的到来,软件的形态将发生巨大的变化。一方面,移动应用和移动互联网领域仍然强力驱动人机交互、设备协同、智能化、安全性等方向的创新,另一方面人工智能也同样驱动软件朝智能化、端边云协同等方向演进。新技术、新场景下应用软件的开发对编程语言提出了新的诉求和挑战。
- 高效编程:
仓颉是一门多范式编程语言,支持函数式、命令式和面向对象等多种范式,包括值类型、类和接口、泛型、代数数据类型、模式匹配、以及高阶函数等特性。此外,仓颉还支持类型推断,能够减轻开发者类型标注的负担;通过一系列简明高效的语法,能够减少冗余书写、提升开发效率;语言内置的各种语法糖和宏(macro)的能力,支持开发者基于仓颉快速开发领域专用语言(DSL),构建领域抽象。
- 安全可靠:
仓颉,作为一款现代编程语言,将安全性置于核心地位。它采用先进的静态类型系统,确保在编译阶段即能捕获类型不匹配的错误,从而显著减少运行时类型错误的风险。同时,仓颉还通过自动内存管理机制,如垃圾回收,来避免内存泄漏和悬挂指针等问题,保证内存安全,并内置了对 null 安全的支持。
除了编译时的类型检查,仓颉还提供了丰富的运行时检查功能,如数组越界检查、类型转换验证、数值溢出检测和字符串编码合规性检查等,这些都能确保程序在运行时能够及时发现并报告错误,从而防止程序崩溃或产生不正确的结果。
- 轻松并发:
仓颉语言采用了一种高效的用户态线程模型,这一模型下的线程极其轻量,每个线程都拥有独立的执行上下文,但内存空间是共享的。对于开发者而言,使用仓颉的用户态线程与使用传统的系统线程体验一致,无需额外的学习成本或编程负担。
从运行时的角度来看,仓颉的用户态线程管理完全由运行时环境负责,不依赖于操作系统的线程管理机制。这种设计使得线程的创建、调度和销毁等操作更加高效,同时也显著减少了系统资源的占用。
为了在多线程环境下避免数据竞争,仓颉语言提供了一套全面的并发对象库。这些并发对象的方法都经过了线程安全设计,因此开发者在多线程环境中调用这些方法与串行编程时并无二致,无需担心并发管理的问题。
除此之外,仓颉编程语言是一种面向全场景应用开发的通用编程语言,可以兼顾开发效率和运行性能,并提供良好的编程体验。还具有以下特点:语法简明高效、多范式编程、类型安全、内存安全、高效并发、兼容语言生态、领域易扩展、助力 UI 开发、内置库功能丰富。
开发篇
标识符:
由英文字母开头,后接零至多个英文字母、数字或下划线“_”,
_123 // 起始下划线 “_” 后不能接数字
3abc // 数字不能出现在头部
while // 不能使用仓颉关键字
基础数据类型包括:
整数、浮点、布尔、字符、字符串、元组、数组、
区间类型:
区间类型用于表示拥有固定步长的序列,区间类型是一个泛型,使用 Range 表示。每个区间类型的实例都会包含 start、end 和 step 三个值。其中,start 和 end 分别表示序列的起始值和终止值,step 表示序列中前后两个元素之间的差值(即步长);start 和 end 的类型相同(即 T 被实例化的类型),step 类型是 Int64,并且它的值不能等于 0。
// Range<T>(start: T, end: T, step: Int64, hasStart: Bool, hasEnd: Bool, isClosed: Bool)
let r1 = Range<Int64>(0, 10, 1, true, true, true) // r1 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
let r2 = Range<Int64>(0, 10, 1, true, true, true) // r2 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r3 = Range<Int64>(10, 0, -2, true, true, false) // r3 contains 10, 8, 6, 4, 2
Unit 类型:
对于那些只关心副作用而不关心值的表达式,它们的类型是 Unit。例如,print 函数、赋值表达式、复合赋值表达式、自增和自减表达式、循环表达式,它们的类型都是 Unit。
Unit 类型只有一个值,也是它的字面量:()。除了赋值、判等和判不等外,Unit 类型不支持其他操作。
Nothing 类型:
Nothing 是一种特殊的类型,它不包含任何值,并且 Nothing 类型是所有类型的子类型。
break、continue、return 和 throw 表达式的类型是 Nothing,程序执行到这些表达式时,它们之后的代码将不会被执行。其中 break、continue 只能在循环体中使用,return 只能在函数体中使用。包围着的循环体“无法穿越”函数边界。
在下面的例子中,break 出现在函数 f 中,外层的 while 循环体不被视作包围着它的循环体;continue 出现在 lambda 表达式中,外层的 while 循环体不被视作包围着它的循环体。
while (true) {func f() {break // Error, break must be used directly inside a loop}let g = { =>continue // Error, continue must be used directly inside a loop}
}
函数
仓颉使用关键字 func 来表示函数定义的开始,func 之后依次是函数名、参数列表、可选的函数返回值类型、函数体。
func add(a: Int64, b: Int64): Int64 {return a + b
}
struct
struct 类型的定义以关键字 struct 开头,后跟 struct 的名字,接着是定义在一对花括号中的 struct 定义体。struct 定义体中可以定义一系列的成员变量、成员属性、静态初始化器、构造函数和成员函数。
struct Rectangle {let width: Int64let height: Int64public init(width: Int64, height: Int64) {this.width = widththis.height = height}public func area() {width * height}
}
枚举类型
enum 类型的定义以关键字 enum 开头,接着是 enum 的名字,之后是定义在一对花括号中的 enum 体,enum 体中定义了若干构造器,多个构造器之间使用 | 进行分隔(第一个构造器之前的 | 是可选的)。上例中定义了一个名为 RGBColor 的 enum 类型,它有 3 个构造器:Red、Green 和 Blue,分别表示 RGB 色彩模式中的红色、绿色和蓝色。
enum RGBColor {| Red | Green | Blue
}
类
class 类型的定义以关键字 class 开头,后跟 class 的名字,接着是定义在一对花括号中的 class 定义体。class 定义体中可以定义一系列的成员变量、成员属性、静态初始化器、构造函数、成员函数和操作符函数。
class Rectangle {let width: Int64let height: Int64public init(width: Int64, height: Int64) {this.width = widththis.height = height}public func area() {width * height}
}
接口
接口使用关键字 interface 声明,其后是接口的标识符 I 和接口的成员。接口成员可被 open 修饰符修饰,并且 open 修饰符是可选的。
当接口 I 声明了一个成员函数 f 之后,要为一个类型实现 I 时,就必须在该类型中实现一个对应的 f 函数。
class Foo <: I {public func f(): Unit {println("Foo")}
}main() {let a = Foo()let b: I = ab.f() // "Foo"
}
结语
在探索仓颉编程语言的旅程中,我们领略了其独特的设计理念、强大的功能和无尽的潜力。从基础的数据类型到复杂的算法结构,仓颉语言展现了一种既注重效率又追求简洁与优雅的编程范式。其枚举类型作为语言中的一个重要组成部分,不仅增强了代码的可读性和类型安全性,还为开发者提供了更多的灵活性和便利性。
然而,仓颉语言仍然是一个不断发展的领域,它将继续吸引来自全球各地的开发者们共同探索和创新。我们期待着未来仓颉语言能够带来更多的惊喜和突破,为解决现实世界中的复杂问题提供更加高效和可靠的编程工具。
在结束这篇文章之际,我们衷心感谢所有为仓颉语言做出贡献的开发者们,是他们的辛勤工作让这门语言得以不断发展和完善。同时,我们也希望更多的开发者能够加入到仓颉语言的社区中来,共同推动这门语言的发展,让编程的世界因仓颉而更加精彩。
最后,让我们以开放的心态和探索的热情,继续前行在仓颉编程语言的道路上,共同创造更加美好的未来。