NOTE阅读文档版本:
语言规约 Cangjie-0.53.18-Spec
具体开发指南 Cangjie-LTS-1.0.3
在阅读 了解仓颉的语言规约时, 难免会涉及到一些仓颉的示例代码, 但 我们对仓颉并不熟悉, 所以可以用 仓颉在线体验 快速验证
有条件当然可以直接 配置Canjie-SDK
WARNING博主在此之前, 基本只接触过C/C++语言, 对大多现代语言都没有了解, 所以在阅读过程中遇到相似的概念, 难免会与C/C++中的相似概念作类比, 见谅
且, 本系列是文档阅读, 而不是仓颉的零基础教学, 所以如果要跟着阅读的话最好有一门编程语言的开发经验
WARNING在阅读仓颉编程语言的开发指南之前, 已经大概阅读了一遍 仓颉编程语言的语言规约,已经对仓颉编程语言有了一个大概的了解
所以在阅读开发指南时,不会对类似: 类、函数、结构体、接口等解释起来较为复杂名称 做出解释
此样式内容, 表示文档原文内容
基础数据类型
区间类型
区间类型用于表示拥有固定步长的序列,区间类型是一个泛型,使用
Range<T>表示当
T被实例化不同的类型时(要求此类型必须支持关系操作符,并且可以和Int64类型的值做加法),会得到不同的区间类型,如最常用的Range<Int64>用于表示整数区间每个区间类型的实例都会包含
start、end和step三个值其中,
start和end分别表示序列的起始值和终止值,step表示序列中前后两个元素之间的差值(即步长);start和end的类型相同(即T被实例化的类型),step类型是Int64,并且它的值不能等于0下面的例子给出了区间类型的实例化方式(关于区间类型定义和其中的属性,详见《仓颉编程语言库 API》):
// Range<T>(start: T, end: T, step: Int64, hasStart: Bool, hasEnd: Bool, isClosed: Bool)let r1 = Range<Int64>(0, 10, 1, true, true, true) // r1 包含 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10let r2 = Range<Int64>(0, 10, 1, true, true, false) // r2 包含 0, 1, 2, 3, 4, 5, 6, 7, 8, 9let r3 = Range<Int64>(10, 0, -2, true, true, false) // r3 包含 10, 8, 6, 4, 2
区间Range, 是一个有限的每个元素之间固定步长的序列, 比如: 1, 2, 3, 4, 5, 6, 7, 8, 元素之家的步长是1
实例化时, 构造函数传入start(表示起始值)、end(表示终止值)和step(表示从起始值到终止值每个元素的步长)
步长可以是正数和负数, 且start和end的大小要符合步长会发生的变化趋势, 但禁止是0
如果Range<Int64>(0, 10, 2, true, true, true), 则 start为0, end为10, 步长为2
最终得到的区间序列, 值为: 0, 2, 4, 6, 8, 10
Range的构造函数还存在另外三个参数: hasStart、hasEnd和isClosed
isClosed表示是否右闭区间, 即是否包含终止值本身
其实文档中的例子就已经很好的说明了
而hasStart和hasEnd大概率是用在数组索引上的Range才有用的
关于Range用在数组索引中, 请参考 访问Array成员
区间类型字面量
区间字面量有两种形式: **“左闭右开”区间和“左闭右闭”**区间
“左闭右开”区间的格式是
start..end : step,它表示一个从start开始,以step为步长,到end(不包含end)为止的区间;“左闭右闭”区间的格式是
start..=end : step,它表示一个从start开始,以step为步长,到end(包含end)为止的区间下面的例子定义了若干区间类型的变量:
let n = 10let r1 = 0..10 : 1 // r1 包含 0, 1, 2, 3, 4, 5, 6, 7, 8, 9let r2 = 0..=n : 1 // r2 包含 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10let r3 = n..0 : -2 // r3 包含 10, 8, 6, 4, 2let r4 = 10..=0 : -2 // r4 包含 10, 8, 6, 4, 2, 0区间字面量中,可以不写
step,此时step默认等于1,但是**step的值不能等于0**另外,区间也有可能是空的(即不包含任何元素的空序列),举例如下:
let r5 = 0..10 // r5 的步长是 1, r5 包含 0, 1, 2, 3, 4, 5, 6, 7, 8, 9let r6 = 0..10 : 0 // Error, 步长不能是 0let r7 = 10..0 : 1 // r7 to r10 是空区间let r8 = 0..10 : -1let r9 = 10..=0 : 1let r10 = 0..=10 : -1注意:
表达式
start..end : step中,当step > 0且start >= end,或者step < 0且start <= end时,start..end : step是一个空区间表达式
start..=end : step中,当step > 0且start > end,或者step < 0且start < end时,start..=end : step是一个空区间
区间字面量的格式是: start..(=)end( : step)
=表示是否有右闭区间, 可以省略
step指定步长, 默认为1, 禁止为0 可以省略
当step的值 无法表示 start到end的变化趋势时, 此字面量表示一个空区间
即:
-
是右开区间时
如果
start >= end,step > 0时 为空区间如果
start <= end,step < 0时 为空区间 -
如果右闭区间时
如果
start > end,step > 0时 为空区间如果
start < end,step < 0时 为空区间
Unit类型
对于那些只关心副作用而不关心值的表达式,它们的类型是
Unit例如,
Unit
Unit类型只有一个值,也是它的字面量:()除了赋值、判等和判不等外,
Unit类型不支持其他操作
仓颉中的Unit可以类比C/C++中的void类型, 表示空, 字面量也只有一个()
Nothing类型
Nothing是一种特殊的类型,它不包含任何值,并且Nothing类型是所有类型的子类型(这当中也包括Unit类型)
break、continue、return和throw表达式的类型是Nothing,程序执行到这些表达式时,它们之后的代码将不会被执行
return只能在函数体中使用,break、continue只能在循环体中使用,参考如下示例:while (true) {func f() {break // Error, break 语句必须直接位于循环内部}let g = { =>continue // Error, continue 语句必须直接位于循环内部}}由于函数的形参和其默认值不属于该函数的函数体,所以下面例子中的
return表达式缺少包围它的函数体——它既不属于外层函数f(因为内层函数定义g已经开始),也不在内层函数g的函数体中(该用例相关内容,请参考嵌套函数):func f() {func g(x!: Int64 = return) { // Error, return 必须在函数体中使用0}1}注意:
目前编译器还不允许在使用类型的地方显式地使用
Nothing类型
Nothing表示什么都不是, 它是所有类型的子类型
return、break、continue和throw表达式, 就是Nothing类型的, 它们之后的代码不会被执行
Nothing类型目前不允许被显式使用