仓颉入门:基础概念
1. 标识符
在仓颉编程语言中,开发者可以给一些程序元素命名,这些名字被称为“标识符”。
学习标识符之前,需要了解一些 Unicode 字符集概念。
1.1 XID_Start(标识符起始字符)
指可以作为标识符第一个字符的字符集合,满足一下条件:
(1)基础起始字符集,包含各种语言的字母、下划线等
(2)排除非字符代码点
(3)排除默认可忽略字符,如:软连字符
常见的XID_Start字符包括:
(1)拉丁字母(A-Z、a-z);
(2)希腊字母、西里尔字母、阿拉伯字母等各种语言的字母;
(3)带重音的字母(如 é、ñ、ü 等);
(4)下划线;
(5)其他语言的表意文字首字符(如中文的 “字”、日文的 “字” 等)。
1.2 XID_Continue(标识符后续字符)
指可以跟随在 XID_Start 之后,作为标识符非首字符的字符集合,满足以下条件:
(1)基础后续字符集,包含字符 + 数字、连接符等;
(2)排除非字符代码点;
XID_Continue 包含 XID_Start 的所有字符,此外还包括:
(1)数字(0-9,以及阿拉伯数字、中文数字、印度数字等);
(2)连接符;
(3)组合符号(如重音符号、变音标记,用于修饰前一个字符)。
仓颉编程语言的标识符分为普通标识符和原始标识符两类,它们遵从不同的命名规则。
1.3 普通标识符
不能和仓颉关键字相同,其取自以下两类字符序列:
1.由 XID_Start 字符开头,后接任意长度的 XID_Continue 字符。由英文字母开头,后接零至多个英文字母、数字或下划线。
2.由一个_开头,后接至少一个 XID_Continue 字符。由一直多个下划线开头,后接一个英文字母,最后可接零至多个英文字母、数字或下划线。

1.4 原始标识符
原始标识符是在普通标识符或仓颉关键字的首尾加上一对反引号,主要用于将仓颉关键字作为标识符的场景。

2. 程序结构
通常,开发者会在扩展名为 .cj 的文本文件中编写仓颉程序,这些程序和文件也被称为源代码和源文件。在程序开发的最后阶段,这些源代码将被编译为特定格式的二进制文件。
在仓颉程序的顶层作用域中,可以定义一系列的变量、函数和自定义类型(如 struct、class、enum 和 interface 等),其中的变量和函数分别被称为全局变量和全局函数。
2.1 变量
变量定义的具体形式为:
修饰符 变量名: 变量类型 = 初始值
修饰符用于设置变量的各类属性,可以有一个或多个,常用的修饰符包括:
(1)不可变修饰符let和可变修饰符var
(2)常量修饰符const
(3)可见性修饰符:private 与 public
(4)静态性修饰符:static,影响成员变量的存储和引用方式
变量名应是一个合法的仓颉标识符
变量类型指定了变量所持有数据的类型
初始值是一个仓颉表达式
例如:
可变变量 var a:Int8 = 1
不可变变量 let b:Int8 = 2 运行时求值
不可变常量 const c:Int8 = 3 编译时求值
当初始值具有明确类型时,可以省略变量类型标注,编译器会自动推断出变量类型。




当let变量没有初始化赋值时,可以被赋值一次。如果没有初始化赋值,被提示:error: variable 'a' is used before initialization
const 变量是一种特殊的变量,它以关键字 const 修饰,定义在编译时完成求值,并且在运行时不可改变的变量。const 变量可以省略类型标注,但是不可省略初始化表达式。
2.2 值类型和引用类型变量
从编译器实现层面看,任何变量总会关联一个值,只是在使用时,对有些变量,将直接取用这个值本身,这被称为值类型变量;而对另一些变量,将这个值作为索引、取用这个索引指示的数据,这被称为引用类型变量。
在仓颉编程语言中,class 和 Array 等类型属于引用类型,其他基础数据类型和 struct 等类型属于值类型。
package HelloWorld
struct Copy{
var data=2025
}
class Share{
var data=2025
}
main() {
let c1=Copy() //struct 值类型
var c2=c1
c2.data=2026
println("${c1.data},${c2.data}")
let s1=Share() //引用类型
let s2=s1
s2.data=2026
println("${s1.data},${s2.data}")
}
2.3 作用域
但在实际应用中,需要考虑一些特殊情况:
1.当程序规模较大时,那些简短的名字很容易重复,即产生命名冲突。
2.结合运行时考虑,在有些代码片段中,另一些程序元素是无效的,对它们的引用会导致运行时错误。
3.在某些逻辑构造中,为了表达元素之间的包含关系,不应通过名字直接访问子元素,而是要通过其父元素名间接访问。
为了应对这些问题,现代编程语言引入了作用域的概念及设计,将名字和程序元素的绑定关系限制在一定范围里。不同作用域之间可以是并列或无关的,也可以是嵌套或包含关系。
package HelloWorld
let e="仓颉"
main() {
println(e)
let e=9
if(e>0){
let e=2025
println(e)
}
println(e)
}
2.4 表达式
表达式是可以求值的程序元素,可以用于变量赋值、函数传值和返回值等场景。
if表达式
if(条件){
分支1
}else{
分支2
}
“let pattern” 属于语法糖。一个 “let pattern” 的构成为 let pattern <- expression,其中各字段含义为:
pattern :模式,用于匹配 expression 的值类型和内容。
**<- **:模式匹配操作符。
expression :表达式,该表达式求值后,再和模式进行匹配。
例如:
package HelloWorld
main() {
let a=Some(4) //存在一个整数
let c=if(let Some(d)<-a){
d //模式匹配成功,将d赋值给c
}else{
0
}
println(c)
}
While表达式
while(条件){
循环体
}
do-while表达式
do{
循环体
}while(条件)
fo-in表达式
for(迭代变量 in 序列){
循环体
}
break 与 continue 表达式
break 用于终止当前循环表达式的执行、转去执行循环表达式之后的代码,continue 用于提前结束本轮循环、进入下一轮循环。
main() {
let numbers=[12,14,25,56,43,63]
for(n in numbers){
if(n % 5==0){
println(n)
break;
}
}
}
package demo
main() {
let numbers=[12,42,53,64,23]
for(n in numbers){
if(n%2==0){
continue
}
println(n)
}
}
2.5 函数
仓颉使用关键字 func 来表示函数定义的开始,func 之后依次是函数名、参数列表、可选的函数返回值类型、函数体。其中,函数名可以是任意的合法标识符,参数列表定义在一对圆括号内(多个参数间使用逗号分隔),参数列表和函数返回值类型(如果存在)之间使用冒号分隔,函数体定义在一对花括号内。
package demo
func add(a:Int64,b:Int64){
return a+b
}
main() {
println(add(2,3))
}

浙公网安备 33010602011771号