仓颉语言入门:核心概念与基础数据类型

目录

1.仓颉语言核心前置概念

[1.1 变量与常量声明](#1.1 变量与常量声明)

[1.2 程序入口与文件规范](#1.2 程序入口与文件规范)

[1.3 值类型与引用类型](#1.3 值类型与引用类型)

2.基础数据类型

[2.1 整数类型](#2.1 整数类型)

[2.2 浮点类型](#2.2 浮点类型)

[2.3 布尔类型](#2.3 布尔类型)

[2.4 字符类型](#2.4 字符类型)

[2.5 字符串类型](#2.5 字符串类型)

[2.6 元组类型](#2.6 元组类型)

[2.7 数组类型](#2.7 数组类型)

[2.8 区间类型](#2.8 区间类型)

[2.9 Unit 类型](#2.9 Unit 类型)

[2.10 Nothing类型](#2.10 Nothing类型)


仓颉语言是华为为鸿蒙生态打造的新一代全场景编程语言,主打原生智能化、天生全场景、高性能、强安全,支持函数式、命令式、面向对象等多范式编程仓颉。作为鸿蒙原生应用开发的核心语言,掌握其基础数据类型是搭建复杂逻辑的第一步。本文将结合代码示例,介绍仓颉的核心概念与基础数据类型。

1.仓颉语言核心前置概念

1.1 变量与常量声明

仓颉是静态类型语言,编译时确定变量类型,支持类型推断,大幅减少冗余标注。声明变量 / 常量的核心关键字如下:

  • let :定义不可变变量 (初始化后不可赋值),对应 Java 的final
  • var :定义可变变量,支持后续赋值
  • 类型标注:使用:指定类型,可省略(编译器自动推断)

1.2 程序入口与文件规范

  • 源文件后缀:.cj
  • 程序入口:顶层作用域的main函数,返回值可为整数类型或Unit(无返回值),参数为Array<String>(可选:如果需要获取程序启动时的命令行参数)

1.3 值类型与引用类型

  • 值类型 :基础数据类型(如IntBool)、struct、元组,【直接存储值,赋值时拷贝】
  • 引用类型classArray,【存储内存地址,赋值时传递引用】

2.基础数据类型

2.1 整数类型

整数类型分为有符号(signed)整数类型无符号(unsigned)整数类型

  • 有符号整数类型 包括 Int8Int16Int32Int64IntNative,分别用于表示编码长度为 8-bit16-bit32-bit64-bit 和平台相关大小的有符号整数值的类型。
  • 无符号整数类型 包括 UInt8UInt16UInt32UInt64UIntNative,分别用于表示编码长度为 8-bit16-bit32-bit64-bit 和平台相关大小的无符号整数值的类型。

对于编码长度为 N 的有符号整数类型,其表示范围为:−2^(N−1)∼2^(N−1)−1;对于编码长度为 N 的无符号整数类型,其表示范围为:0∼2^N−1。

Int64 类型适合的情况下,首选 Int64 类型 ,因为 Int64 的表示范围足够大,并且整数类型字面量在没有类型上下文的情况下默认推断为 Int64 类型,可以避免不必要的类型转换。

代码示例:整数类型使用

java 复制代码
main(){
// 整数类型声明与进制表示
let decInt = 10;          // 十进制,类型推断为Int
let binInt = 0b1101;      // 二进制
let octInt = 0o144;       // 八进制
let hexInt = 0x1F;        // 十六进制

// 指定位宽的整数
let maxInt8: Int8 = 127i8;
let maxUInt8: UInt8 = 255u8;

// 输出结果
println("十进制: ${decInt}");
println("二进制转十进制: ${binInt}");
println("二进制转八进制: ${octInt}");
println("二进制转十六进制: ${hexInt}");
println("Int8最大值: ${maxInt8}");
println("UInt8最大值: ${maxUInt8}");
}

运行结果:

2.2 浮点类型

浮点类型包括 Float16、**Float32**和 Float64,分别用于表示编码长度为 16-bit32-bit64-bit 的浮点数(带小数部分的数字,如 3.14159、8.24 和 0.1 等)的类型。Float16Float32Float64 分别对应 IEEE 754 中的半精度格式(即 binary16)、单精度格式(即 binary32)和双精度格式(即 binary64)。

Float64 的精度(有效数字位)约为 15 位,Float32 的精度(有效数字位)约为 6 位,Float16 的精度(有效数字位)约为 3 位。使用哪种浮点类型,取决于代码中需要处理的浮点数的性质和范围。

代码示例:浮点类型使用

java 复制代码
main(){
// 浮点类型声明与科学计数法
let float32Num: Float32 = 3.14159f32;
let float64Num = 1.23e-4;  // 科学计数法,推断为Float64
let inf = 1.0 / 0.0;       // 正无穷大
let nan = 0.0 / 0.0;       // 非数

// 输出结果
println("单精度浮点数: ${float32Num}");
println("科学计数法: ${float64Num}");
println("无穷大: ${inf}");
println("非数: ${nan}");
}

运行结果:

2.3 布尔类型

布尔类型使用 Bool 表示,用来表示逻辑中的真和假。布尔类型只有两个字面量:truefalse

代码示例:布尔类型与逻辑运算

java 复制代码
main(){
// 布尔类型声明
let isAdult: Bool = true;
let hasPermission = false;

// 逻辑运算:&&(与)、||(或)、!(非)
let canAccess = isAdult && !hasPermission;
let isVip = isAdult || hasPermission;

// 输出结果
println("是否可访问: ${canAccess}");
println("是否为VIP: ${isVip}");
}

运行结果:

2.4 字符类型

表示单个 Unicode 字符,区别于 Java 的char(仅支持 UTF-16),仓颉Rune 支持全量 Unicode 字符,占用 4 字节。

字符类型字面量有三种形式:单个字符转义字符通用字符 。一个 Rune 字面量由字符 r 开头 ,后跟一个由一对单引号或双引号包含的字符。

单个字符的字符字面量举例:

java 复制代码
let a: Rune = r'a'
let b: Rune = r"b"

转义字符是指在一个字符序列中对后面的字符进行另一种解释的字符。转义字符使用**转义符号 \**开头,后面加需要转义的字符。举例如下:

java 复制代码
let slash: Rune = r'\\'
let newLine: Rune = r'\n'
let tab: Rune = r'\t'

通用字符以**\u**开头,后面加上定义在一对花括号中的 1~8 个十六进制数,即可表示对应的 Unicode 值代表的字符。举例如下:

java 复制代码
main() {
    let he: Rune = r'\u{4f60}'
    let llo: Rune = r'\u{597d}'
    print(he)
    print(llo)
}

编译并执行上述代码,输出结果为:

2.5 字符串类型

字符串类型使用 String 表示,用于表达文本数据,由一串 Unicode 字符组合而成。值类型 (区别于 Java 的引用类型String

代码示例:字符串类型操作

java 复制代码
main() {
// 单行字符串
let singleLine = "Hello, Cangjie!";

// 多行字符串:三双引号包裹,保留换行与缩进
let multiLine = """
    仓颉语言
    鸿蒙原生开发首选
    多范式编程支持
    """;

// 插值字符串:${}嵌入变量/表达式
let name = "开发者";
let interpolated = "你好,${name}!当前时间:${2026}年";

// 字符串拼接:+ 运算符
let combined = singleLine + " - " + interpolated;

// 输出结果
println("单行字符串: ${singleLine}");
println("多行字符串: ${multiLine}");
println("拼接结果: ${combined}");
}

运行结果:

2.6 元组类型

轻量级、不可变、类型安全的复合结构,允许将不同类型的值组合成一个值,至少包含 2 个元素

元组的长度是固定的,即一旦定义了一个元组类型的实例,它的长度不能再被更改。

元组类型是不可变类型,即一旦定义了一个元组类型的实例,它的内容(即单个元素)不能再被更新。但整个元组可被覆盖替换。

代码示例:元组的声明与使用

java 复制代码
main() {
// 普通元组:类型推断为(Int, String, Bool)
let user = (1001, "张三", true);

// 命名元组:通过标签访问元素,更易读
let student = (2004, "李四", 95.5f64);

// 访问元素:索引(从0开始)或标签
println("用户ID: ${user[0]}");
println("学生姓名: ${student[1]}");
println("学生成绩: ${student[2]}");

// 解构赋值:将元组元素赋值给多个变量
let (uid, uname, isMale) = user;
println("解构后的用户名: ${uname}");
}

运行结果:

2.7 数组类型

可以使用Array类型来构造单一元素类型,有序序列的数据。

仓颉使用 **Array<T>**来表示 Array 类型。T 表示 Array 的元素类型,T 可以是任意类型。

引用类型,存储相同类型的可变长度序列,支持下标访问(从 0 开始),自带越界检查。

代码示例:数组的声明与操作

java 复制代码
main() {
// 数组声明:类型标注或推断
let arr1: Array<Int> = [1, 2, 3, 4, 5];
let arr2 = ["苹果", "香蕉", "橙子"];  // 推断为Array<String>

var arr3 = [10, 20, 30];
arr3[1] = 25;          // 修改指定下标元素

// 访问元素与长度
println("数组1长度: ${arr1.size}");
println("修改后的arr3: ${arr3}");
println("arr2第一个元素: ${arr2[0]}");

// 初始化数组
let arr4 = Array<Int>(5,{i=>i+1});  // 包含1到5的整数
println("使用lambda表达式初始化数组: ${arr4}");

let arr5 = Array<Int>(3,repeat:0);
println("使用repeat初始化数组: ${arr5}");

// 获取某一段 Array 的元素
let arr6 = [0, 1, 2, 3, 4, 5, 6]
let arr7 = arr6[0..5]
println("获取arr6的一段元素: ${arr7}");
}

运行结果:

2.8 区间类型

区间类型用于表示拥有固定步长的序列,区间类型是一个泛型,使用**Range<T>**表示。

每个区间类型的实例都会包含 startendstep 三个值。其中,startend 分别表示序列的起始值和终止值,step 表示序列中前后两个元素之间的差值(即步长);startend 的类型相同(即 T 被实例化的类型),step 类型是 Int64,并且它的值不能等于 0

区间字面量有两种形式:

  • "左闭右开"区间 的格式是 start..end : step,它表示一个从 start 开始,以 step 为步长,到 end(不包含 end)为止的区间;
  • "左闭右闭"区间 的格式是 start..=end : step,它表示一个从 start 开始,以 step 为步长,到 end(包含 end)为止的区间。

区间字面量中,可以不写 step,此时 step 默认等于 1,但是step 的值不能等于 0。另外,区间也有可能是空的(即不包含任何元素的空序列)。

代码示例:区间类型的使用

java 复制代码
main() {
// 闭区间:1到5,包含5
let closedRange = 1..=5;
// 半开区间:0到9,不包含9
let halfOpenRange = 0..9;

// 区间遍历
println("闭区间遍历:");
for (i in closedRange) {
    print("${i}");
}
println("\n半开区间遍历:");
for (i in halfOpenRange) {
    print("${i}");
}

// 区间属性
println("\n闭区间起始: ${closedRange.start}");
println("闭区间结束: ${closedRange.end}");
}

运行结果:

2.9 Unit 类型

Unit 类型只有一个值 ,也是它的字面量:()。除了赋值、判等和判不等外,Unit 类型不支持其他操作。

对于那些只关心副作用而不关心值的表达式,它们的类型是 Unit。例如,print 函数、赋值表达式、复合赋值表达式、自增和自减表达式、循环表达式。

代码示例:Unit 类型的使用

java 复制代码
main() {
// 无返回值函数,返回值类型为Unit
func printHello(): Unit {
    println("Hello, Unit!");
}

// 调用函数,返回值为()
let result = printHello();
println("Unit实例: ${result}");  // 输出:()
}

运行结果:

2.10 Nothing类型

Nothing 是一种特殊的类型,它不包含任何值,并且 Nothing 类型是所有类型的子类型(这当中也包括 Unit 类型)。

break**、continuereturn** 和 throw 表达式的类型是 Nothing,程序执行到这些表达式时,它们之后的代码将不会被执行。return 只能在函数体中使用,breakcontinue 只能在循环体中使用。

注意:目前编译器还不允许在使用类型的地方显式地使用 Nothing 类型。

相关推荐
FleetingLore6 小时前
如何系统地推导语法系统的意外情况
编程语言
长安牧笛6 小时前
车载模型白天晚上自动切换,自动切昼夜模型,颠覆统一模型,输出稳定识别。
python·编程语言
_waylau4 天前
跟老卫学仓颉编程语言开发:浮点类型
人工智能·华为·harmonyos·鸿蒙·鸿蒙系统·仓颉
华科大胡子5 天前
《Effective C++》学习笔记:条款02
c++·编程语言·inline·const·enum·define
坚果的博客7 天前
cjman:仓颉生态的轻量化工程管理工具
仓颉
怕浪猫10 天前
第16章:标准库精讲(二)net/http、json、time
后端·go·编程语言
Java后端的Ai之路10 天前
【Python 教程17】-扩展 Python
开发语言·后端·python·编程语言·拓展
_waylau11 天前
跟老卫学仓颉编程语言开发:整数类型
算法·华为·harmonyos·鸿蒙·鸿蒙系统·仓颉
怕浪猫11 天前
第15章、标准库精讲(一)——fmt、os、io、bufio
后端·go·编程语言