本节介绍仓颉的变量与常量。其中变量又可以细分为不可变变量及可变变量。使用let关键字声明不可变变量,使用var关键字声明可变变量。

本节示例可以在“variable_demo”应用下找到。

不可变的变量

在仓颉里,使用let关键字声明不可变(immutable)变量,这有点反直觉,比如下面的例子:

// 声明不变量a,并初始化值1
let a = 1;
println("a: ${a}");

// 错误!不能对不可变变量a二次赋值
a = 2;

上述例子:

  • let关键字声明了不可变变量a,并初始化值1;
  • 试图将变量a,重新赋值为2.

但这个例子无法通过仓颉编译器的校验,会得到如下的错误提示:

error: cannot assign to immutable value
 ==> main.cj:9:5:
  |
9 |     a = 2;
  |     ^^^^^
  |
note: variable 'a' is immutable
 ==> main.cj:4:9:
  |
4 |     let a = 1;
  |         ^
  |

1 error generated, 1 error printed.

上面的错误信息已经指出错误的原因是“cannot assign to immutable value”,意味着不能对不可变变量a进行二次赋值。

1. 那么为什么要将变量设计为不可变呢?

那“不可变的变量”那还能叫变量吗?

仓颉设计者认为变量默认不可变,是仓颉的优势之一,可以充分利用仓颉提供的安全性和简单并发性来编写代码。当然,你仍然有机会使用可变的变量。

2. 什么是变量?

如果你初次学习编程语言,变量会是一个比较抽象的概念。以仓颉语言来说,声明一个变量就是申请一块内存,内存的大小由变量的类型决定,类型会在后续的章节介绍。

比例上面的例子中:

let a = 1;

使用let关键字声明一个变量a,同时把1存放到变量里面。此时,我们可以说变量中存储了1,也可以说这块内存中存储了1。这里我们并没有声明变量a的数据类型,仓颉会自定根据变量值来推导出a的数据类型,这与很多动态语言的行为相似。

具体怎么来理解呢?

内存就像这个鸡蛋收纳盒(如下图2-1所示),我们为每一个蛋格编码(这个编码就相当于内存地址)。声明一个变量a,相当于找到一个空格把它叫做a,同时把鸡蛋放到这个空格里面。我们可以把任何一个空格叫做a,它不过是为蛋格的编码起了一个别名。把1赋值给变量a的过程称为“变量绑定”。

内存就像这个鸡蛋收纳盒

3. 未使用的变量

如果你创建了一个变量却不在任何地方使用它,仓颉编译器通常会给你一个警告,因为这可能会是个bug。比如下面例子

// 声明未使用的变量c,并初始化值1
let c = 1;
// 告警!c没有任何地方用到

变量c没有任何地方使用,编译阶段就会警告,信息如下:

warning: unused variable:'c'
  ==> main.cj:13:9:
   |
13 |     let c = 1;
   |         ^ unused variable
   |
   # note: this warning can be suppressed by setting the compiler option `-Woff unused`

1 warning generated, 1 warning printed.

可变的变量

在仓颉里面,使用var关键字声明可变变量。比如下面的例子:

// 声明可变变量b,并初始化值1
var b = 1;
println("b: ${b}");

// 修改变量b的值为2
b = 2;
println("b: ${b}");

上述例子执行之后输出内容如下:

b: 1
b: 2

常量

使用关键字const来声明常量(constant)。类似于不可变变量,常量的值是不允许改变的,下面是一个声明常量的例子:

// 声明常量ONE_DAY_IN_SECONDS,并初始化值
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
println("ONE_DAY_IN_SECONDS: ${ONE_DAY_IN_SECONDS}");

上述例子,声明了常量ONE_DAY_IN_SECONDS,它的值被设置为60(一分钟内的秒数)乘以60(一小时内的分钟数)再乘以24(1天的小时数)的结果。仓颉对常量的命名约定是在单词之间使用全大写加下划线。编译器能够在编译时计算一组有限的操作,也就是常量表达式。常量表达式使我们可以以更容易理解和验证的方式写出常量值,而不是直接将常量设置为86400。

上述例子执行之后输出内容如下:

ONE_DAY_IN_SECONDS: 86400
1. 不可变变量和常量什么区别

既然不可变变量是不可变的,那是否就等同于常量了呢?常量与变量还是有一些区别:

  • 声明常量使用const关键字而不是let。
  • 常量可以在任何作用域中声明,包括全局作用域,这在一个值需要被很多部分的代码用到时很有用。
  • 常量只能被设置为常量表达式,而不可以是其他任何只能在运行时计算出的值。
2. 常量的使用场景

在声明它的作用域之中,常量在整个程序生命周期中都有效,此属性使得常量可以作为多处代码使用的全局范围的值,例如一个游戏中所有玩家可以获取的最高分或者光速。

在实际使用中,最好将程序中用到的硬编码值都声明为常量,对于代码后续的维护有莫大的帮助。如果将来需要更改硬编码的值,你也只需要在代码中更改一处即可。

参考引用

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐