仓颉编程语言:基本概念

标识符

在仓颉编程语言中,开发者可以给一些程序元素命名,这些名字也被称为“标识符”,标识符分为普通标识符和原始标识符两类,它们分别遵从不同的命名规则。

普通标识符不能和仓颉关键字相同,可以取自以下两类字符序列:

  • 由英文字母开头,后接零至多个英文字母、数字或下划线“_”。
  • 由一至多个下划线“”开头,后接一个英文字母,最后可接零至多个英文字母、数字或下划线“”。

例如,以下每行字符串都是合法的普通标识符:

abc
_abc
abc_
a1b2c3
a_b_c
a1_b2_c3

以下每行字符串都是不合法的普通标识符:

ab&c  // 使用了非法字符 “&”
_123  // 起始下划线 “_” 后不能接数字
3abc  // 数字不能出现在头部
while // 不能使用仓颉关键字

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

例如,以下每行字符串都是合法的原始标识符:

`abc`
`_abc`
`a1b2c3`
`if`
`while`

以下每行字符串,由于反引号内的部分是不合法的普通标识符,所以它们整体也是不合法的原始标识符:

`ab&c`
`_123`
`3abc`

程序结构

通常,我们都会在扩展名为 .cj 的文本文件中编写仓颉程序,这些程序和文件也被称为源代码和源文件,在程序开发的最后阶段,这些源代码将被编译为特定格式的二进制文件。

在仓颉程序的顶层作用域中,可以定义一系列的变量、函数和自定义类型(如 struct、class、enum 和 interface 等),其中的变量和函数分别被称为全局变量全局函数。如果要将仓颉程序编译为可执行文件,您需要在顶层作用域中定义一个 main 函数作为程序入口,它可以有 Array 类型的参数,也可以没有参数,它的返回值类型可以是整数类型或 Unit 类型。

注意

定义 main 函数时,不需要写 func 修饰符。此外,如果需要获取程序启动时的命令行参数,可以声明和使用 Array 类型参数。

例如在以下程序中,我们在顶层作用域定义了全局变量 a 和全局函数 b,还有自定义类型 C、D 和 E,以及作为程序入口的 main 函数。

// example.cj
let a = 2023
func b() {}
struct C {}
class D {}
enum E { F | G }

main() {
    println(a)
}

在非顶层作用域中不能定义上述自定义类型,但可以定义变量和函数,称之为局部变量局部函数。特别地,对于定义在自定义类型中的变量和函数,称之为成员变量成员函数

注意

enum 和 interface 中仅支持定义成员函数。

例如在以下程序中,我们在顶层作用域定义了全局函数 a 和自定义类型 A,在函数 a 中定义了局部变量 b 和局部函数 c,在自定义类型 A 中定义了成员变量 b 和成员函数 c。

// example.cj
func a() {
    let b = 2023
    func c() {
        println(b)
    }
    c()
}

class A {
    let b = 2024
    public func c() {
        println(b)
    }
}

main() {
    a()
    A().c()
}

运行以上程序,将输出:

20232024

变量

在仓颉编程语言中,一个变量由对应的变量名、数据(值)和若干属性构成,开发者通过变量名访问变量对应的数据,但访问操作需要遵从相关属性的约束(如数据类型、可变性和可见性等)。

变量定义的具体形式为:

修饰符 变量名: 变量类型 = 初始值

其中修饰符用于设置变量的各类属性,可以有一个或多个,常用的修饰符包括:

  • 可变性修饰符:let 与 var,分别对应不可变和可变属性,可变性决定了变量被初始化后其值还能否改变,仓颉变量也由此分为不可变变量和可变变量两类。
  • 可见性修饰符:private 与 public 等,影响全局变量和成员变量的可引用范围,详见后续章节的相关介绍。
  • 静态性修饰符:static,影响成员变量的存储和引用方式,详见后续章节的相关介绍。

在定义仓颉变量时,可变性修饰符是必要的,在此基础上,还可以根据需要添加其他修饰符。

  • 变量名应是一个合法的仓颉标识符。
  • 变量类型指定了变量所持有数据的类型。当初始值具有明确类型时,可以省略变量类型标注,此时编译器可以自动推断出变量类型。
  • 初始值是一个仓颉表达式,用于初始化变量,如果标注了变量类型,需要保证初始值类型和变量类型一致。在定义全局变量或静态成员变量时,必须指定初始值。在定义局部变量或实例成员变量时,可以省略初始值,但需要标注变量类型,同时要在此变量被引用前完成初始化,否则编译会报错。

例如,下列程序定义了两个 Int64 类型的不可变变量 a 和可变变量 b,随后修改了变量 b 的值,并调用 println 函数打印 a 与 b 的值。

main() {
    let a: Int64 = 20
    var b: Int64 = 12
    b = 23
    println("${a}${b}")
}

编译运行此程序,将输出:

2023

如果尝试修改不可变变量,编译时会报错,例如:

main() {
    let pi: Float64 = 3.14159
    pi = 2.71828 // Error, cannot assign to immutable value
}

当初始值具有明确类型时,可以省略变量类型标注,例如:

main() {    let a: Int64 = 2023    let b = a    println("a - b = ${a - b}&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值