仓颉基础大揭秘:数据类型的奇妙世界


                                                                                                                                                <span id="OSC_h2_1"></span> 

1 概述

1.1 背景介绍

仓颉编程语言作为一款面向全场景应用开发的现代编程语言,通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的 IDE工具链支持,为开发者打造友好开发体验和卓越程序性能。

案例结合代码体验,让大家更直观的了解仓颉语言中的基础数据类型。

1.2 适用对象

  • 个人开发者
  • 高校学生

1.3 案例时间

本案例总时长预计50分钟。

1.4 案例流程

11a0c75e6fc2b97a6b805317f20ea48c.png

说明:

① 进入华为开发者空间,登录云主机;
② 使用CodeArts IDE for Cangjie编程和运行仓颉代码。

1.5 资源总览

资源名称 规格 单价(元) 时长(分钟)
开发者空间 – 云主机 鲲鹏通用计算增强型 kc2 | 4vCPUs | 8G | Ubuntu 免费 50

最新案例动态,请查阅  仓颉基础大揭秘:数据类型的奇妙世界  。小伙伴快来领取华为开发者空间,进入云主机桌面版实操吧!

2 运行测试环境准备

2.1 开发者空间配置

面向广大开发者群体,华为开发者空间提供一个随时访问的“开发桌面云主机”、丰富的“预配置工具集合”和灵活使用的“场景化资源池”,开发者开箱即用,快速体验华为根技术和资源。

领取云主机后可以直接进入华为开发者空间工作台界面,点击进入桌面连接云主机。没有领取在开发者空间根据指引领取配置云主机即可,云主机配置参考1.5资源总览

2427bdcdb98bfd50840ca130685be10a.PNG

552fc96c3b58a06e294e4a760ae719e3.PNG

2.2 创建仓颉程序

点击桌面CodeArts IDE for Cangjie,打开编辑器,点击新建工程,保持默认配置,点击创建

产物类型说明

  • executable,可执行文件;
  • static,静态库,是一组预先编译好的目标文件的集合;
  • dynamic,动态库,是一种在程序运行时才被加载到内存中的库文件,多个程序共享一个动态库副本,而不是像静态库那样每个程序都包含一份完整的副本。

28acbca9146a8a6aacbfdd4f6ac3791b.png

2.3 运行仓颉工程

创建完成后,打开src/main.cj,参考下面代码简单修改后,点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

复制
<strong>package</strong> demo
<span style="color:#697070">// 第一个仓颉程序</span>
main(): Int64 {
    <span style="color:#397300">println</span>(<span style="color:#880000">"hello world"</span>)
    <span style="color:#397300">println</span>(<span style="color:#880000">"你好,仓颉!"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

(* 注意:后续替换main.cj文件代码时,package demo保留,demo为实际创建的项目名称)

(* 仓颉注释语法:// 符号之后写单行注释,也可以在一对 /* 和 */ 符号之间写多行注释)

d1e16b48f5f9620fafe9fc59ae62a367.png

到这里,我们第一个仓颉程序就运行成功啦!后面案例中的示例代码都可以放到main.cj文件中进行执行,接下来我们继续探索仓颉语言。

3 仓颉中的基础数据类型

3.1 整数类型

整数类型分为:有符号整数类型和无符号整数类型。

有符号整数类型包括 Int8、Int16、Int32、Int64 和 IntNative,分别用于表示编码长度为 8-bit、16-bit、32-bit、64-bit 和平台相关大小的有符号整数值的类型。

无符号整数类型包括 UInt8、UInt16、UInt32、UInt64 和 UIntNative,分别用于表示编码长度为 8-bit、16-bit、32-bit、64-bit 和平台相关大小的无符号整数值的类型。

编码长度为 N 的有符号整数类型,其表示范围为:7e2b7f4d83653aa56083f7f1ef0e144c.png

编码长度为 N 的无符号整数类型,其表示范围为:8bc12a8f3d614234383159dc5d670ae6.png
 
举例说明:

Int8:编码长度为8的有符号整数类型,范围为:57ed23d8ad03c1abee01a203c00a7be5.png

UInt16:编码长度为16的无符号整数类型,范围为:730bfaff2bdcec13b5efa4ddb776d932.png

3.1.1 整数类型字面量

整数类型字面量有 4 种进制表示形式:

  • 二进制:使用 0b 或 0B 前缀
  • 八进制:使用0o(小写字母o)或0O(大写字母O)前缀
  • 十进制:没有前缀
  • 十六进制:使用 0x 或 0X 前缀

备注:在各进制表示中,可以使用下划线 _ 充当分隔符的作用,方便识别数值的位数,如 0b0001_1000。

对于整数类型字面量,如果它的值超出了上下文要求的整数类型的表示范围,编译器将会报错。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():<span style="color:#880000">Int64</span> {
     <span style="color:#697070">// Error, 128 out of the range of Int8</span>
    <strong>let</strong> x: <span style="color:#880000">Int8</span> <span style="color:#ab5656">=</span> <span style="color:#880000">128</span>     
    <span style="color:#697070">// Error, 256 out of the range of UInt8 </span>
    <strong>let</strong> y: <span style="color:#880000">UInt8</span> <span style="color:#ab5656">=</span> <span style="color:#880000">256</span>       
    <span style="color:#697070">// Error, 0x8000_0000 out of the range of Int32  </span>
    <strong>let</strong> z: <span style="color:#880000">Int32</span> <span style="color:#ab5656">=</span> <span style="color:#880000">0x8000_0000</span> 
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:代码复制完成后,编译器直接提示报错。

5de7230f1462a0f3a2eed8ac5270c7d8.PNG

在使用整数类型字面量时,可以通过加入后缀来明确整数字面量的类型,后缀与类型的对应为:

后缀 类型 后缀 类型
i8 Int8 u8 UInt8
i16 Int16 u16 UInt16
i32 Int32 u32 UInt32
i64 Int64 u64 UInt64

加入了后缀的整数字面量可以像下面的方式来使用,具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <span style="color:#697070">// x is 100 with type Int8</span>
    <strong>var</strong> x = <span style="color:#880000">100i</span>8      
    <span style="color:#397300">println</span>(<span style="color:#880000">"x的值为:${x}"</span>)
    <span style="color:#697070">// y is 16 with type UInt64</span>
    <strong>var</strong> y = <span style="color:#880000">0x10</span>u64    
    <span style="color:#397300">println</span>(<span style="color:#880000">"y的值为:${y}"</span>)
    <span style="color:#697070">// z is 282 with type Int32</span>
    <strong>var</strong> z = <span style="color:#880000">0</span>o432i32   
    <span style="color:#397300">println</span>(<span style="color:#880000">"z的值为:${z}"</span>) 
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

3f6e39e8476ea8070f16d65d32c3389d.PNG

3.1.2 字符字节字面量

仓颉编程语言支持字符字节字面量,以方便使用 ASCII 码表示 UInt8 类型的值。字符字节字面量由字符 b、一对标识首尾的单引号、以及一个 ASCII 字符组成,具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <span style="color:#697070">// a is 120 with type UInt8</span>
    <strong>var</strong> a = b<span style="color:#880000">'x'</span> 
    println(<span style="color:#880000">"a的值为:<span>${a}</span>"</span>) 
    <span style="color:#697070">// b is 10 with type UInt8</span>
    <strong>var</strong> b = b<span style="color:#880000">'\n'</span> 
    println(<span style="color:#880000">"b的值为:<span>${b}</span>"</span>) 
    <span style="color:#697070">// c is 120 with type UInt8</span>
    <strong>var</strong> c = b<span style="color:#880000">'\u{78}'</span> 
    println(<span style="color:#880000">"c的值为:<span>${c}</span>"</span>) 
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

535a13f2ee6ecb274792d3b91bc9c5ee.PNG

3.1.3 整数类型支持的操作

整数类型默认支持的操作符包括:算术操作符、位操作符、关系操作符、自增和自减操作符、赋值操作符、复合赋值操作符。

算术操作符:

一元负号(-)、加法(+)、减法(-)、乘法(*)、除法(/)、取模(%)、幂运算(**)。具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <span style="color:#697070">// 负号</span>
    let p0 = -<span style="color:#880000">10</span>
    println(<span style="color:#880000">"负号:p0=<span>${p0}</span>"</span>)
    <span style="color:#697070">// 加法</span>
    let p1 = <span style="color:#880000">10</span> + <span style="color:#880000">5</span>
    println(<span style="color:#880000">"加法运算:p1=<span>${p1}</span>"</span>)
    <span style="color:#697070">// 减法</span>
    let p2 = <span style="color:#880000">10</span> - <span style="color:#880000">5</span>
    println(<span style="color:#880000">"减法运算:p2=<span>${p2}</span>"</span>)
    <span style="color:#697070">// 乘法</span>
    let p3 = <span style="color:#880000">10</span> * <span style="color:#880000">5</span>
    println(<span style="color:#880000">"乘法运算:p3=<span>${p3}</span>"</span>)
    <span style="color:#697070">// 除法</span>
    let p4 = <span style="color:#880000">10</span> / <span style="color:#880000">5</span>
    println(<span style="color:#880000">"除法运算:p4=<span>${p4}</span>"</span>)
    <span style="color:#697070">// 取模</span>
    let p5 = <span style="color:#880000">10</span> % <span style="color:#880000">5</span>
    println(<span style="color:#880000">"取模运算:p5=<span>${p5}</span>"</span>)
    <span style="color:#697070">// 幂运算</span>
    let p6 = <span style="color:#880000">10</span> ** <span style="color:#880000">2</span>
    println(<span style="color:#880000">"幂运算:p6=<span>${p6}</span>"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

21e58a12eb8620c93981fa5d502055d3.PNG

位操作符:

按位求反(!)、左移(<<)、右移(>>)、按位与(&)、按位异或(^)、按位或(|)。注意,按位与、按位异或和按位或操作符要求左右操作数是相同的整数类型。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    let p3 = <span style="color:#880000">3</span>
    let p2 =<span style="color:#880000">2</span>
    <span style="color:#697070">// 取反!</span>
    let b = <span style="color:#669955">true</span>
    println(<span style="color:#880000">"取反操作:b=<span>${!b}</span>"</span>)
    <span style="color:#697070">// 左移(<<)</span>
    let p4 = p3 << <span style="color:#880000">1</span>
    println(<span style="color:#880000">"左移:p4 = <span>${p4}</span>"</span>)
    <span style="color:#697070">//右移(>>)</span>
    let p5 = p3 >> <span style="color:#880000">1</span>
    println(<span style="color:#880000">"右移:p5 = <span>${p5}</span>"</span>)
    <span style="color:#697070">//按位与(&)</span>
    println(<span style="color:#880000">"按位与: <span>${p3 & p2}</span>"</span>)
    <span style="color:#697070">//按位异或(^)</span>
    println(<span style="color:#880000">"按位异或: <span>${p3 ^ p2}</span>"</span>)
    <span style="color:#697070">//按位或(|)</span>
    println(<span style="color:#880000">"按位或: <span>${p3 | p2}</span>"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

be04a892d09bdd36e11bc4302bfeb3a8.PNG

关系运算符:

小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、相等(==)、不等(!=)。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <span style="color:#397300">let</span> p1 = 1
    <span style="color:#397300">let</span> p2 = 2
    println(<span style="color:#880000">"p1小于p2:<span style="color:#ab5656">${p1 < p2}</span>"</span>)
    println(<span style="color:#880000">"p1大于p2:<span style="color:#ab5656">${p1 > p2}</span>"</span>)
    println(<span style="color:#880000">"p1小于等于p2:<span style="color:#ab5656">${p1 <= p2}</span>"</span>)
    println(<span style="color:#880000">"p1大于等于p2:<span style="color:#ab5656">${p1 >= p2}</span>"</span>)
    println(<span style="color:#880000">"p1相等于p2:<span style="color:#ab5656">${p1 == p2}</span>"</span>)
    println(<span style="color:#880000">"p1不等于p2:<span style="color:#ab5656">${p1 != p2}</span>"</span>)
    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

26f0211f4b55fa030bb9612dc3019292.PNG

赋值操作符和自增和自减操作符:

赋值操作符即 =,自增和自减操作符包括:自增(++)和自减(–)。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <strong>var</strong> a = <span style="color:#880000">10</span>
    <span style="color:#697070">//赋值</span>
    a = <span style="color:#880000">11</span>
    println(<span style="color:#880000">"变量a重新赋值:<span>${a}</span>"</span>)
    <span style="color:#697070">//自增(++)</span>
    a++
    println(<span style="color:#880000">"变量a自增后的值为:<span>${a}</span>"</span>)
    <span style="color:#697070">//自减(--)</span>
    a--
    println(<span style="color:#880000">"变量a自减后的值为:<span>${a}</span>"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

9f2389dc546e737c819b47be4a20b6a1.PNG

复合赋值操作符:

+=、-=、*=、/=、%=、**=、<<=、>>=、&=、^=、|=。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <strong>var</strong> a = <span style="color:#880000">10</span>
    a+=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为10,a+=2的值为:<span>${a}</span>"</span>)
    a-=<span style="color:#880000">1</span>
    println(<span style="color:#880000">"a的值为12,a-=1的值为:<span>${a}</span>"</span>)
    a*=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为11,a*=2的值为:<span>${a}</span>"</span>)
    a/=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为22,a/=2的值为:<span>${a}</span>"</span>)
    a%=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为11,a%=2的值为:<span>${a}</span>"</span>)
    a**=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为1,a**=2的值为:<span>${a}</span>"</span>)
    a<<=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为1,a<<=2的值为:<span>${a}</span>"</span>)
    a>>=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为4,a>>=2的值为:<span>${a}</span>"</span>)
    a&=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为1,a&=2的值为:<span>${a}</span>"</span>)
    a^=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为0,a^=2的值为:<span>${a}</span>"</span>)
    a|=<span style="color:#880000">2</span>
    println(<span style="color:#880000">"a的值为2,a|=2的值为:<span>${a}</span>"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

125eb23b4e3a0044750b74bd3494af95.PNG

3.2 浮点类型

浮点类型包括 Float16、 Float32 和 Float64,分别用于表示编码长度为16-bit、32-bit 和 64-bit 的浮点数。

Float64 的精度约为小数点后 15 位,Float32 的精度约为小数点后6位,Float16 的精度约为小数点后 3 位。

3.2.1 浮点类型的字面量

浮点类型字面量有两种进制表示形式:十进制、十六进制。

在十进制表示中,一个浮点字面量至少要包含一个整数部分或一个小数部分,没有小数部分时必须包含指数部分(以 e 或 E 为前缀,底数为 10)。

在十六进制表示中,一个浮点字面量除了至少要包含一个整数部分或小数部分(以 0x 或 0X 为前缀),同时必须包含指数部分(以 p 或 P 为前缀,底数为 2)。

下面的例子展示了浮点字面量的使用,具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <span style="color:#397300">let</span> a: Float32 = 3.14
    println(<span style="color:#880000">"a的值为:<span style="color:#ab5656">${a}</span>"</span>)
    <span style="color:#397300">let</span> b: Float32 = 2e3
    println(<span style="color:#880000">"b的值为:<span style="color:#ab5656">${b}</span>"</span>)
    <span style="color:#397300">let</span> c: Float32 = 2.4e-1
    println(<span style="color:#880000">"c的值为:<span style="color:#ab5656">${c}</span>"</span>)
    <span style="color:#397300">let</span> d: Float64 = .123e2
    println(<span style="color:#880000">"d的值为:<span style="color:#ab5656">${d}</span>"</span>)
    <span style="color:#397300">let</span> e: Float64 = 0x1.1p0
    println(<span style="color:#880000">"e的值为:<span style="color:#ab5656">${e}</span>"</span>)
    <span style="color:#397300">let</span> f: Float64 = 0x1p2
    println(<span style="color:#880000">"f的值为:<span style="color:#ab5656">${f}</span>"</span>)
    <span style="color:#397300">let</span> g: Float64 = 0x.2p4
    println(<span style="color:#880000">"g的值为:<span style="color:#ab5656">${g}</span>"</span>)
    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

355f9e5f8e0250f743a13ec37f97632d.PNG

在使用十进制浮点数字面量时,可以通过加入后缀来明确浮点数字面量的类型,后缀与类型的对应为:

后缀为f16—>对应的类型为Float16;

后缀为f32—>对应的类型为Float32;

后缀为f64—>对应的类型为Float64;

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {
    <span style="color:#397300">let</span> a = 3.14f32   
    println(<span style="color:#880000">"a的值为:<span style="color:#ab5656">${a}</span>"</span>)
    <span style="color:#397300">let</span> b = 2e3f32    
    println(<span style="color:#880000">"b的值为:<span style="color:#ab5656">${b}</span>"</span>)
    <span style="color:#397300">let</span> c = 2.4e-1f64 
    println(<span style="color:#880000">"c的值为:<span style="color:#ab5656">${c}</span>"</span>)
    <span style="color:#397300">let</span> d = .123e2f64 
    println(<span style="color:#880000">"d的值为:<span style="color:#ab5656">${d}</span>"</span>)
    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

a95fcc9b8a75122c0ab28459edf7ddde.PNG

3.2.2 浮点类型支持的操作

浮点类型默认支持的操作符包括:算术操作符、关系操作符、赋值操作符、复合赋值操作符。浮点类型不支持自增和自减操作符。

具体请参考3.1.3 整数类型支持的操作。

3.3 布尔类型

布尔类型使用Bool表示,用来表示逻辑中的真和假。

布尔类型的字面量:

布尔类型只有两个字面量:true和false。具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {
    <span style="color:#397300">let</span> a: Bool = <span style="color:#669955">true</span>
    println(<span style="color:#880000">"布尔类型a的值为:<span style="color:#ab5656">${a}</span>"</span>)
    <span style="color:#397300">let</span> b: Bool = <span style="color:#669955">false</span> 
    println(<span style="color:#880000">"布尔类型b的值为:<span style="color:#ab5656">${b}</span>"</span>)
    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

245b25bec971d46bbdd312408bd2710b.PNG

布尔类型支持的操作:

布尔类型支持的操作符包括:逻辑操作符(逻辑非 !,逻辑与 &&,逻辑或 ||)、部分关系操作符(== 和 !=)、赋值操作符、部分复合赋值操作符(&&= 和 ||=)。

3.4 字符类型

字符类型使用Rune表示,可以表示 Unicode 字符集中的所有字符。

字符类型字面量:

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

单个字符字面量由字符 r 开头,后跟由一对单引号或双引号包含的单个字符。

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

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

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {
    // 单个字符
    let a: Rune = <span style="color:#880000">r'a'</span>
    println(<span style="color:#880000">"单个字符a的值为:${a}"</span>)
    let b: Rune = <span style="color:#880000">r"b"</span>
    println(<span style="color:#880000">"单个字符b的值为:${b}"</span>)
    println()
    // 转义字符
    let c: Rune = <span style="color:#880000">r'\\'</span>
    println(<span style="color:#880000">"转义字符c的值为:${c}"</span>)
    let d: Rune = <span style="color:#880000">r'\n'</span>
    println(<span style="color:#880000">"转义字符d的值为:${d}"</span>)
    let e: Rune = <span style="color:#880000">r'\t'</span>
    println(<span style="color:#880000">"转义字符e的值为:${e}"</span>)
    println()   
    // 通用字符
    let f: Rune = <span style="color:#880000">r'\u{4f60}'</span>
    <span style="color:#397300">print</span>(<span style="color:#880000">"${f}"</span>)
    let g: Rune = <span style="color:#880000">r'\u{597d}'</span>
    <span style="color:#397300">print</span>(<span style="color:#880000">"${g}"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

b4c224aed8ead418464ca726bdef04db.PNG

字符类型支持的操作:

字符类型仅支持关系操作符:小于(<)、大于(>)、小于等于(<=)、大于等于(>=)、相等(==)、不等(!=)。比较的是字符的 Unicode 值。

3.5 字符串类型

字符串类型使用String表示,用于表达文本数据,由一串 Unicode 字符组合而成。

3.5.1 字符串字面量

字符串字面量分为三类:单行字符串字面量,多行字符串字面量,多行原始字符串字面量。

单行字符串字面量的内容定义在一对单引号或一对双引号之内,引号中的内容可以是任意数量的(除了用于定义字符串字面量的非转义的引号和单独出现的 \ 之外的)任意字符。单行字符串字面量只能写在同一行,不能跨越多行。

多行字符串字面量开头结尾需各存在三个双引号(”””)或三个单引号(”’)。字面量的内容从开头的三个引号换行后的第一行开始,到遇到的第一个非转义的三个引号为止,之间的内容可以是任意数量的(除单独出现的 \ 之外的)任意字符。不同于单行字符串字面量,多行字符串字面量可以跨越多行。

多行原始字符串字面量以一个或多个井号(#)和一个单引号(’)或双引号(”)开头,后跟任意数量的合法字符,直到出现与字符串开头相同的引号和与字符串开头相同数量的井号为止。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    // 单行字符串字面量
    <span style="color:#397300">let</span> s1: String = <span style="color:#880000">""</span>
    <span style="color:#397300">let</span> s2 = <span style="color:#880000">'Hello Cangjie Lang'</span>
    <span style="color:#397300">let</span> s3 = <span style="color:#880000">"\"Hello Cangjie Lang\""</span>
    <span style="color:#397300">let</span> s4 = <span style="color:#880000">'Hello Cangjie Lang\n'</span>
    println(<span style="color:#880000">"单行字符串s1的值为:<span style="color:#ab5656">${s1}</span>"</span>)
    println(<span style="color:#880000">"单行字符串s2的值为:<span style="color:#ab5656">${s2}</span>"</span>)
    println(<span style="color:#880000">"单行字符串s3的值为:<span style="color:#ab5656">${s3}</span>"</span>)
    println(<span style="color:#880000">"单行字符串s4的值为:<span style="color:#ab5656">${s4}</span>"</span>)

    // 多行字符串字面量
    <span style="color:#397300">let</span> s5: String = <span style="color:#880000">""</span>
<span style="color:#880000">"
    你好,
    仓颉
    "</span>
<span style="color:#880000">""</span>
    <span style="color:#397300">let</span> s6 = <span style="color:#880000">''</span>
<span style="color:#880000">'
    Hello,
    Cangjie Lang'</span>
<span style="color:#880000">''</span>
    println(<span style="color:#880000">"多行字符串s5的值为:<span style="color:#ab5656">${s5}</span>"</span>)
    println(<span style="color:#880000">"多行字符串s6的值为:<span style="color:#ab5656">${s6}</span>"</span>)

    // 多行原始字符串
    <span style="color:#397300">let</span> s7: String = <span style="color:#697070">#""#</span>
    <span style="color:#397300">let</span> s8 = <span style="color:#697070">##'\n'##</span>
    <span style="color:#397300">let</span> s9 = <span style="color:#697070">###"</span>
    Hello,
    Cangjie
    Lang<span style="color:#880000">"###
    println("</span>多行原始字符串s7的值为:<span style="color:#ab5656">${s7}</span>
<span style="color:#880000">")
    println("</span>多行原始字符串s8的值为:<span style="color:#ab5656">${s8}</span>
<span style="color:#880000">")
    println("</span>多行原始字符串s9的值为:<span style="color:#ab5656">${s9}</span>
<span style="color:#880000">")
    return 0
}
</span>

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

ab3ab61ac40c22dfeff7bd6869e6110b.PNG

终端窗口打印的完整内容:

复制
<strong>developer@developer:~/IDEProjects/demo$ cjpm run</strong>
<strong>单行字符串s1的值为:</strong>
<strong>单行字符串s2的值为:Hello Cangjie Lang</strong>
<strong>单行字符串s3的值为:"Hello Cangjie Lang"</strong>
<strong>单行字符串s4的值为:Hello Cangjie Lang</strong>

<strong>多行字符串s5的值为:    你好,</strong>
    仓颉

<strong>多行字符串s6的值为:    Hello,</strong>
    Cangjie Lang
<strong>多行原始字符串s7的值为:</strong>
<strong>多行原始字符串s8的值为:\n</strong>
<strong>多行原始字符串s9的值为:</strong>
    Hello,
    Cangjie
    Lang

cjpm run finished

3.5.2 插值字符串

插值字符串是一种包含一个或多个插值表达式的字符串字面量,通过将表达式插入到字符串中,可以有效避免字符串拼接的问题。

虽然直到现在才介绍它,但其实它早已经出现在之前的示例代码中,因为经常在 println 函数中输出非字符串类型的变量值,例如 println(“${x}”)。

插值表达式必须用花括号 {} 包起来,并在 {} 之前加上 $ 前缀。{} 中可以包含一个或者多个声明或表达式。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {
    // 插字符串
    <span style="color:#397300">let</span> fruit = <span style="color:#880000">"苹果"</span>
    <span style="color:#397300">let</span> count = 10
    <span style="color:#397300">let</span> price = 500
    <span style="color:#397300">let</span> s = <span style="color:#880000">"我买了<span style="color:#ab5656">${count ** 2}</span>个<span style="color:#ab5656">${fruit}</span>,花费了<span style="color:#ab5656">${price}</span>元钱"</span>
    println(s)
    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

7b5866b92fe56df4660360e263785923.PNG

3.5.3 字符串类型支持的操作

字符串类型支持使用关系操作符进行比较,支持使用 + 进行拼接。下面的例子展示了字符串类型的判等、拼接、拆分和替换:

具体代码操如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <strong>let</strong> s1 = <span style="color:#880000">"abc"</span>
    <strong>var</strong> s2 = <span style="color:#880000">"ABC"</span>
    <span style="color:#697070">// 字符串比较</span>
    <strong>let</strong> r1 = s1 == <span>s2
    <strong>println</strong>(<span><span style="color:#880000">"The result of 'abc' == 'ABC' is: ${r1}"</span></span>)
    <span style="color:#697070">// 字符串拼接</span>
    <strong>let</strong> r2</span> = s1 + <span>s2
    <strong>println</strong>(<span><span style="color:#880000">"The result of 'abc' + 'ABC' is: ${r2}"</span></span>)
    <span style="color:#697070">// 拆分</span>
    <strong>let</strong> s5</span> =  r2.split(<span style="color:#880000">"A"</span>)
    println(s5.toString())
    <span style="color:#697070">// 替换</span>
    <strong>let</strong> s6=  r2.replace(<span style="color:#880000">"ABC"</span>, <span style="color:#880000">"EFG"</span>)
    println(s6)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

51ef8a921dc8095ec8315a8c7ce31060.PNG

3.6 元组类型

元组(Tuple)可以将多个不同的类型组合在一起,成为一个新的类型。元组类型使用 (T1, T2, …, TN) 表示,其中 T1 到 TN 可以是任意类型,不同类型间使用逗号(,)连接。

注意:

  • 元组至少是二元。

    (Int64, Float64) 表示一个二元组类型,(Int64, Float64, String) 表示一个三元组类型。

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

  • 元组类型是不可变类型,即一旦定义了一个元组类型的实例,它的内容不能再被更新。

3.6.1 元组类型的字面量

元组类型的字面量使用 (e1, e2, …, eN) 表示,其中e1到eN是表达式,多个表达式之间使用逗号分隔。

元组支持通过t[index]的方式访问某个具体位置的元素,其中t是一个元组,index是下标,并且index只能是从0开始且小于元组元素个数的整数类型字面量,否则,编译报错。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {
    <span style="color:#697070">// 定义元组</span>
    let t: (Float64, String) = (<span style="color:#880000">3.14</span>, <span style="color:#880000">"PI"</span>)
    <span style="color:#697070">// 取元组的第一个元素</span>
    <strong>var</strong> a = t[<span style="color:#880000">0</span>]
    println(<span style="color:#880000">"元组t的第一个元素为:<span>${a}</span>"</span>)
    <span style="color:#697070">// 取元组的第二个元素</span>
    <strong>var</strong> b = t[<span style="color:#880000">1</span>]
    println(<span style="color:#880000">"元组t的第二个元素为:<span>${b}</span>"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

fc47d6bd3bcaed8492b6a376bf1e18d5.PNG

3.6.2 元组类型的类型参数

可以为元组类型标记显式的类型参数名,下面例子中的name和price就是 类型参数名。

对于一个元组类型,只允许统一写类型参数名,或者统一不写类型参数名,不允许交替存在,并且参数名本身不能作为变量使用或用于访问元组中元素。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的代码。(保留package)

复制
 <span style="color:#697070">// name 和 price 就是 类型参数名</span>
<span><strong>func</strong> <strong>getFruitPrice</strong> <span>()</span></span>: (name: String, price: Int64) {
    <strong>return</strong> (<span style="color:#880000">"banana"</span>, <span style="color:#880000">10</span>)
}

main():Int64 {

    <span style="color:#697070">// 报错,统一写类型参数名,或者统一不写类型参数名,不允许交替存在</span>
    <span style="color:#697070">//let a: (name: String, Int64) = ("banana", 5) </span>

    <span style="color:#697070">// 报错,参数名本身不能作为变量使用或用于访问元组中元素</span>
    <span style="color:#697070">//b.name </span>

    <span style="color:#697070">// ok</span>
    let b: (name: String, price: Int64) = getFruitPrice()
    <span style="color:#697070">// 取元组的第一个元素</span>
    <strong>var</strong> x = b[<span style="color:#880000">0</span>]
    <span style="color:#397300">println</span>(<span style="color:#880000">"元组b的第一个元素为:${x}"</span>)
    <span style="color:#697070">// 取元组的第二个元素</span>
    <strong>var</strong> y = b[<span style="color:#880000">1</span>]
    <span style="color:#397300">println</span>(<span style="color:#880000">"元组b的第二个元素为:${y}"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

eb80cad77fc6fa40f49ba52b2db28205.PNG

3.7 数组类型

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

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

3.7.1 访问Array成员

当需要对Array的所有元素进行访问时,可以使用for-in循环遍历Array的所有元素。

Array是按元素插入顺序排列的,因此对Array遍历的顺序总是恒定的。

当需要知道某个Array包含的元素个数时,可以使用size属性获得对应信息。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 <strong>main</strong>():<strong>Int64</strong> {
    <span style="color:#697070">// 定义数组</span>
    <strong>let</strong> <span>languages</span>: <strong>Array</strong><<strong>String</strong>> = [<span style="color:#880000">"Python"</span>,<span style="color:#880000">"Cangjie"</span>,<span style="color:#880000">"Java"</span>,<span style="color:#880000">"ArkTS"</span>,<span style="color:#880000">"C++"</span>]
    <span style="color:#697070">// 遍历数组中的元素</span>
    <strong>for</strong>(language <strong>in</strong> languages){
        <strong>println</strong>(<span style="color:#880000">"数组的元素是:${language}"</span>)
    }
    <strong>if</strong> (languages.<span>size</span> != <span style="color:#880000">0</span>) {
        <span style="color:#697070">// 数组的长度size</span>
         <strong>println</strong>(<span style="color:#880000">"The size of languages is ${languages.size}"</span>)
    }
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

3427a15c27848c212dc778f0dd380f14.PNG

3.7.2 修改Array

Array是一种长度不变的Collection类型,因此Array没有提供添加和删除元素的成员函数。

但是Array允许对其中的元素进行修改,同样使用下标语法。

对Array 素的修改会影响到该实例的所有引用。

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {

    let arr: Array<Int64> = [<span style="color:#880000">0</span>, <span style="color:#880000">1</span>, <span style="color:#880000">2</span>, <span style="color:#880000">3</span>, <span style="color:#880000">4</span>, <span style="color:#880000">5</span>]
    <span style="color:#697070">// 通过下标,修改数组的第一个元素</span>
    arr[<span style="color:#880000">0</span>] = <span style="color:#880000">3</span>
    println(<span style="color:#880000">"The first element is <span>${arr[<span style="color:#880000">0</span>]}</span>"</span>)

    <span style="color:#697070">// Array 元素的修改会影响到该实例的所有引用</span>
    let new_array = arr
    new_array[<span style="color:#880000">1</span>] = <span style="color:#880000">9</span>
    println(<span style="color:#880000">"new_array: <span>${new_array.toString()}</span>"</span>)
    println(<span style="color:#880000">"arr: <span>${arr.toString()}</span>"</span>)
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。
0421.png

3.8 其它类型

包括区间类型、Unit类型、Nothing类型。

3.8.1 区间类型

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

区间类型定义:

Range(start: T, end: T, step: Int64, hasStart: Bool, hasEnd: Bool, isClosed: Bool)

start:起始值

end:终止值

step:前后两个元素之间的差值(步长),步长不能等于0

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <span style="color:#397300">let</span> r1 = Range<Int64>(0, 10, 1, <span style="color:#669955">true</span>, <span style="color:#669955">true</span>, <span style="color:#669955">true</span>) 
    <span style="color:#397300">print</span>(<span style="color:#880000">"r1包含的元素有:"</span>)
    <strong>for</strong>(key <strong>in</strong> r1.iterator()){
          <span style="color:#397300">print</span>(<span style="color:#880000">"<span style="color:#ab5656">${key}</span>"</span>+<span style="color:#880000">" "</span>)
    }

    println()

    <span style="color:#397300">let</span> r2 = Range<Int64>(0, 10, 1, <span style="color:#669955">false</span>, <span style="color:#669955">false</span>, <span style="color:#669955">false</span>) 
    <span style="color:#397300">print</span>(<span style="color:#880000">"r2包含的元素有:"</span>)
    <strong>for</strong>(key <strong>in</strong> r2.iterator()){
          <span style="color:#397300">print</span>(<span style="color:#880000">"<span style="color:#ab5656">${key}</span>"</span>+<span style="color:#880000">" "</span>)
    }
    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

dfe911a6c7b0cb567bbcc26cafbec890.PNG

区间类型字面量:

区间字面量有两种形式:“左闭右开”区间和“左闭右闭”区间。

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

具体代码操作如下:

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
 main():Int64 {
    <span style="color:#397300">let</span> n = 12
    <span style="color:#397300">let</span> r1 = 6..n : 1   
    <span style="color:#397300">print</span>(<span style="color:#880000">"r1包含的元素有:"</span>)
    <strong>for</strong>(key <strong>in</strong> r1.iterator()){
          <span style="color:#397300">print</span>(<span style="color:#880000">"<span style="color:#ab5656">${key}</span>"</span>+<span style="color:#880000">" "</span>)
    }
    println()
    <span style="color:#397300">let</span> r2 = 6..=n : 1   
    <span style="color:#397300">print</span>(<span style="color:#880000">"r2包含的元素有:"</span>)
    <strong>for</strong>(key <strong>in</strong> r2.iterator()){
          <span style="color:#397300">print</span>(<span style="color:#880000">"<span style="color:#ab5656">${key}</span>"</span>+<span style="color:#880000">" "</span>)
    }

    <span style="color:#397300">return</span> 0
}

Step2:点击编辑器右上角运行按钮直接运行,终端窗口可以看到打印内容。

f010f83cfcdf66ce3675320b1f43a263.PNG

3.8.2 Unit 类型

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

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

3.8.3 Nothing类型

Nothing是一种特殊的类型,它不包含任何值,并且Nothing类型是所有类型的子类型。

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

Step1:复制以下代码,替换main.cj文件中的main函数。

复制
main():Int64 {
    <strong>while</strong> (<span style="color:#669955">true</span>) {
        <span>func <strong>f</strong>()</span> {
            <span style="color:#697070">// break 只能在循环体中使用</span>
            <strong>break</strong> 
        }
        <strong>let</strong> g = { =>
            <span style="color:#697070">// continue 只能在循环体中使用</span>
            <strong>continue</strong> 
        }
    }
    <strong>return</strong> <span style="color:#880000">0</span>
}

Step2:代码复制完成后,编译器直接提示报错。

8b41abe0c658c03bc18bcd4fdc99693f.PNG

至此,《仓颉基础大揭秘:数据类型的奇妙世界》案例内容已全部完成。

如果想了解更多仓颉编程语言知识可以访问:https://cangjie-lang.cn/

                                                                                </div>



Source link

未经允许不得转载:紫竹林-程序员中文网 » 仓颉基础大揭秘:数据类型的奇妙世界

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
关于我们 免责申明 意见反馈 隐私政策
程序员中文网:公益在线网站,帮助学习者快速成长!
关注微信 技术交流
推荐文章
每天精选资源文章推送
推荐文章
随时随地碎片化学习
推荐文章
发现有趣的