整数类型
有符号和无符号
有符号整数类型包括 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 和平台相关大小的无符号整数值的类型。
这个比其他语言定义丰富,一般就给个int,就是相当于这里的IntNative
字面量
整数类型字面量有 4 种进制表示形式:二进制(使用 0b 或 0B 前缀)、八进制(使用 0o 或 0O 前缀)、十进制(没有前缀)、十六进制(使用 0x 或 0X 前缀)。
在 Int64 类型适合的情况下,首选 Int64 类型,因为 Int64 的表示范围足够大,并且整数类型字面量在没有类型上下文的情况下默认推断为 Int64 类型,可以避免不必要的类型转换。
-
在使用整数类型字面量时,可以通过加入后缀来明确整数字面量的类型
var x = 100i8 // x is 100 with type Int8
var y = 0x10u64 // y is 16 with type UInt64
var z = 0o432i32 // z is 282 with type Int32
- 仓颉编程语言支持字符字节字面量,以方便使用 ASCII 码表示 UInt8 类型的值。字符字节字面量由字符 b、一对标识首尾的单引号、以及一个 ASCII 字符组成。
var a = b'x' // a is 120 with type UInt8
var b = b'\n' // b is 10 with type UInt8
var c = b'\u{78}' // c is 120 with type UInt8
这个比较特殊,其他地方很少见。有些场景下能带来方便,比如字符x的ASCII 码,就是b'x',这就是个整数,具体数值不用管,只要知道是字符a的ASCII 码,是个整数就可以了。不然的话,代码中给120,谁能想到这是字符x的ASCII 码
幂运算
** 的左操作数只能为 Int64 类型或 Float64 类型。
当左操作数类型为 Int64 时,右操作数只能为 UInt64 类型,表达式的类型为 Int64。
当左操作数类型为 Float64 时,右操作数只能为 Int64 类型或 Float64 类型,表达式的类型为 Float64。
let p1 = 2 ** 3 // p1 = 8
let p2 = 2 ** UInt64(3 ** 2) // p2 = 512
let p3 = 2.0 ** 3.0 // p3 = 8.0
let p4 = 2.0 ** 3 ** 2 // p4 = 512.0
let p5 = 2.0 ** 3.0 // p5 = 8.0
let p6 = 2.0 ** 3.0 ** 2.0 // p6 = 512.0
这个比较特殊,其他地方很少见。
浮点类型
浮点类型包括 Float16、 Float32 和 Float64,分别用于表示编码长度为 16-bit、 32-bit 和 64-bit 的浮点数(带小数部分的数字,如 3.14159、8.24 和 0.1 等)的类型。Float16、 Float32 和 Float64 分别对应 IEEE 754 中的半精度格式(即 binary16)、单精度格式(即 binary32)和双精度格式(即 binary64)。
在使用十进制浮点数字面量时,可以通过加入后缀来明确浮点数字面量的类型
let a = 3.14f32 // a is 3.14 with type Float32
let b = 2e3f32 // b is 2e3 with type Float32
let c = 2.4e-1f64 // c is 2.4e-1 with type Float64
let d = .123e2f64 // d is .123e2 with type Float64
布尔类型
- 布尔类型只有两个字面量:true 和 false。
let a: Bool = true
let b: Bool = false
字符类型
字符类型使用 Rune 表示,可以表示 Unicode 字符集中的所有字符。
一个 Rune 字面量由字符 r 开头,后跟一个由一对单引号或双引号包含的字符。
let a: Rune = r'a'
let b: Rune = r"b"
- 转义字符是指在一个字符序列中对后面的字符进行另一种解释的字符。转义字符使用转义符号 \ 开头,后面加需要转义的字符。
let slash: Rune = r'\\'
let newLine: Rune = r'\n'
let tab: Rune = r'\t'
- 通用字符以 \u 开头,后面加上定义在一对花括号中的 1~8 个十六进制数,即可表示对应的 Unicode 值代表的字符。
main() {
let he: Rune = r'\u{4f60}'
let llo: Rune = r'\u{597d}'
print(he)
print(llo)
}
你好
字符串类型
字符串类型使用 String 表示,用于表达文本数据,由一串 Unicode 字符组合而成。
单行字符串字面量的内容定义在一对单引号或一对双引号之内。
let s1: String = ""
let s2 = 'Hello Cangjie Lang'
let s3 = "\"Hello Cangjie Lang\""
let s4 = 'Hello Cangjie Lang\n'
- 多行字符串字面量开头结尾需各存在三个双引号(""")或三个单引号(''')。
let s1: String = """
"""
let s2 = '''
Hello,
Cangjie Lang'''
- 多行原始字符串字面量以一个或多个井号(#)和一个单引号(')或双引号(")开头,后跟任意数量的合法字符,直到出现与字符串开头相同的引号和与字符串开头相同数量的井号为止。
let s1: String = #""#
let s2 = ##'\n'##
let s3 = ###"
Hello,
Cangjie
Lang"###
- 值表达式必须用花括号 {} 包起来,并在 {} 之前加上 $ 前缀。
整体上,字符串方面跟Swift差不多
元组类型
- 元组类型是不可变类型,即一旦定义了一个元组类型的实例,它的内容不能再被更新。
var tuple = (true, false)
tuple[0] = false // Error, 'tuple element' can not be assigned
元组支持通过 t[index] 的方式访问某个具体位置的元素
在赋值表达式中,可使用元组字面量对表达式的右值进行解构
var a: Int64
var b: String
var c: Unit
var f = { => ((1, "abc"), ())}
((a, b), c) = f() // value of a is 1, value of b is "abc", value of c is '()'
((a, b), _) = ((2, "def"), 3.0) // value of a is 2, value of b is "def", 3.0 is ignored
- 可以为元组类型标记显式的类型参数名
func getFruitPrice (): (name: String, price: Int64) {
return ("banana", 10)
}
- 对于一个元组类型,只允许统一写类型参数名,或者统一不写类型参数名,不允许交替存在。
let c: (name: String, Int64) = ("banana", 5) // Error
数组类型
- 仓颉使用 Array<T> 来表示 Array 类型。T 表示 Array 的元素类型,T 可以是任意类型。
var a: Array<Int64> = ... // Array whose element type is Int64
var b: Array<String> = ... // Array whose element type is String
- 元素类型不相同的 Array 是不相同的类型,所以它们之间不可以互相赋值。
b = a // Type mismatch
- 如果我们想获取某一段 Array 的元素,可以在下标中传入 Range 类型的值,就可以一次性取得 Range 对应范围的一段 Array。
let arr1 = [0, 1, 2, 3, 4, 5, 6]
let arr2 = arr1[0..5] // arr2 contains the elements 0, 1, 2, 3, 4
- 当省略 start 时,Range 会从 0 开始;当省略 end 时,Range 的 end 会延续到最后一位。
let arr1 = [0, 1, 2, 3, 4, 5, 6]
let arr2 = arr1[..3] // arr2 contains elements 0, 1, 2
let arr3 = arr1[2..] // arr3 contains elements 2, 3, 4, 5, 6
当我们需要知道某个 Array 包含的元素个数时,可以使用 size 属性获得对应信息。
Array 是引用类型,因此 Array 在作为表达式使用时不会拷贝副本,同一个 Array 实例的所有引用都会共享同样的数据。
let arr1 = [0, 1, 2]
let arr2 = arr1
arr2[0] = 3
// arr1 contains elements 3, 1, 2
// arr2 contains elements 3, 1, 2
VArray
- 仓颉编程语言引入了值类型数组 VArray<T, N 是一个固定的语法,通过 $ 加上一个 Int64 类型的数值字面量表示这个值类型数组的长度。
type varr1 = VArray<Int64, $3> // Ok
type varr2 = VArray // Error
- VArray 可以由一个数组的字面量来进行初始化,左值 a 必须标识出 VArray 的实例化类型
var a: VArray<Int64, $3> = [1, 2, 3]
VArray的引入不知道有什么用,不是很理解。
区间类型
区间类型用于表示拥有固定步长的序列,使用 Range<T> 表示。如最常用的 Range<Int64> 用于表示整数区间。
每个区间类型的实例都会包含 start、end 和 step 三个值。其中,start 和 end 分别表示序列的起始值和终止值,step 表示序列中前后两个元素之间的差值(即步长);start 和 end 的类型相同(即 T 被实例化的类型),step 类型是 Int64,并且它的值不能等于 0。
// 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 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
let r2 = Range<Int64>(0, 10, 1, true, true, false) // r2 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r3 = Range<Int64>(10, 0, -2, true, true, false) // r3 contains 10, 8, 6, 4, 2
“左闭右开”区间的格式是 start..end : step,它表示一个从 start 开始,以 step 为步长,到 end(不包含 end)为止的区间。
“左闭右闭”区间的格式是 start..=end : step,它表示一个从 start 开始,以 step 为步长,到 end(包含 end)为止的区间。
let n = 10
let r1 = 0..10 : 1 // r1 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r2 = 0..=n : 1 // r2 contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
let r3 = n..0 : -2 // r3 contains 10, 8, 6, 4, 2
let r4 = 10..=0 : -2 // r4 contains 10, 8, 6, 4, 2, 0
- 区间字面量中,可以不写 step,此时 step 默认等于 1,但是注意,step 的值不能等于 0。另外,区间也有可能是空的(即不包含任何元素的空序列)
let r5 = 0..10 // the step of r5 is 1, and it contains 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
let r6 = 0..10 : 0 // Error, step cannot be 0
let r7 = 10..0 : 1 // r7 to r10 are empty ranges
let r8 = 0..10 : -1
let r9 = 10..=0 : 1
let r10 = 0..=10 : -1
Unit类型
对于那些只关心副作用而不关心值的表达式,它们的类型是 Unit。例如,print 函数、赋值表达式、复合赋值表达式、自增和自减表达式、循环表达式,它们的类型都是 Unit。
Unit 类型只有一个值,也是它的字面量:()。除了赋值、判等和判不等外,Unit 类型不支持其他操作。
其他地方没见过,不知道这是干嘛的
Nothing类型
Nothing 是一种特殊的类型,它不包含任何值,并且 Nothing 类型是所有类型的子类型。
break、continue、return 和 throw 表达式的类型是 Nothing,程序执行到这些表达式时,它们之后的代码将不会被执行。其中 break、continue 只能在循环体中使用,return 只能在函数体中使用。
其他地方没见过,不知道这是干嘛的