基本类型
本章详细的讲述基本内置类型,以及可用于它们的操作符。
布尔类型
在nim中boolean类型用被命名为bool,它包含两个预定义的值:true和false。while,if,elif,when语句中的条件类型需要是bool类型。
这些操作符:not,and,or,xor,<, <=, >, >=, !=, ==都为bool类型定义了。
and和or操作符执行简捷评估(自己理解:当and或or链接多个表达式的时候,比如:p1 and p1,只有当p1为真时,才会评估p2)。
例如:
while p != nil and p.name != "xyz":
# p.name is not evaluated if p == nil 如果p==nil,不会评估p.name
p = p.next
字符型
在nim中字符类型被命名为char。它的大小是一个字节。因此它不能表示一个UTF-8字符,只是它的一部分。这样做的原因是效率:在绝大多数情况下使用,由此产生的程序仍将会处理UTF-8,因此UTF-8是特意为这设计的。字符常量用单引号括起来。
字符可以用==, <, <=, >, >=操作符作比较。$操作符将一个字符型转化为一个字符串型。字符不能混合整形;为了得到一个字符的序号值使用ord过程,将一个整形转化为一个字符型用chr过程。
字符串
在nim中字符串变量是易变的,所以拓展字符串是很有效率的。nim中的字符串以\0结束,并有一定的长度。可以用内置的len函数取得字符串的长度,字符串长不包括结束的\0.访问终端的\0不是错误的,经并且常可以利用结尾的0来简化程序。
if s[i] == 'a' and s[i+1] == 'b':
# no need to check whether ``i < len(s)``!
...
对于字符串的赋值操作是用来复制字符串。你可以使用&操作符用来连结字符串以及add添加字符串。
字符串是按字典序进行比较的。所有的比较操作符都是可以使用的。按照规定,所有的字符串都是UTF-8字符串,但这不是强制的。例如,当从二进制文件读取字符串的时候,它们仅仅是一个字节序列。这个s[i]下标操作意味着字符串s的第i个字节,不是第i个字符。(注:unichar是两字节长的char,代表unicode的一个字符)
字符串变量用一个特殊的值进行初始化,叫做nil。然而,由于性能的原因大多数字符串操作不能处理nil(引起产生一个异常)。你可以用空字符串""而不是nil作为这个空值。但是""经常在堆中创建一个字符串对象,所以在这里要做个权衡。
整型
nim有这些内置的整数类型:int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64。
默认的整数类型是int。整型常量可以有一个类型后缀来标记它们成为另外一种整数类型:
let
x = 0 # x is of type ``int`` x是int类型
y = 0'i8 # y is of type ``int8`` y是int8类型
z = 0'i64 # z is of type ``int64`` z是int64类型
u = 0'u # u is of type ``uint`` u是uint类型
整型经常被用来计算驻留内存里的对象,所以整型的与指针有相同的大小。
常见的操作符+ - * div mod < <= == != > >=都已为整形定义。and,or,xor,not操作符也为整形定义并且提供按位操作。左移位用shl操作,右移位用shr操作。移位操作经常将它们的参数作为无符号数处理。通常的乘法或者除法可以实现算术移位。
无符号操作所有环绕,它们不能导致overflow(上溢)或者underflow(下溢)错误。
在表达中使用不同的整形类型时将会执行自动类型转换。然而,如果类型转换丢失信息,就会抛出EOutOfRange异常(如果这个错误无法在编译时检测)
浮点类型
nim有这些内置的float类型:float float32 float64。
默认的float类型是float。在当前的实现中,float总是占64位。
float字面值可以用一个类型后缀将它们标记成为另一种float类型:
var
x = 0.0 # x is of type ``float`` x是float类型
y = 0.0'f32 # y is of type ``float32`` y是float32类型
z = 0.0'f64 # z is of type ``float64`` z是float64类型
通常的操作符+ - * / < <= == != > >=已经为float定义,并且遵守IEEE规范。
在表达式中用不同的float类型将执行自动类型转换:较小的类型转换成更大的类型。整形不能自动的转换为float类型,反之亦然。toInt和toFloat过程可以用于整型和浮点类型的转换。
类型转换
在nim中的基本类型转换是通过用类型作为一个函数执行的:(基本数据类型的关键字本身就是一个方法,可以用这些方法完成类型转换)
var
x: int32 = 1.int32 # same as calling int32(1) 相当于调用int32(1)
y: int8 = int8('a') # 'a' == 97'i8 'a'==97'i8
z: float = 2.5 # int(2.5) rounds down to 2 int(2.5)转化为2
sum: int = int(x) + int(y) + int(z) # sum == 100
内置类型表示
如前面所提到的,内置的$操作符可以将任意基本类型转化为一个字符串型,然后你可以用echo过程将它们打印输出到屏幕。然而,高级类型或者你自己定义的类型不会与$操作符协同工作,直到你为它们定义了$操作符。有时,你仅仅想调试一个复杂类型的当前值而不必写其$运算符。你可以使用repr过程,它有效于任何类型甚至是带有周期的复杂数据图。下面的例子展示了,即使对于基本类型在$和repr之间也存在不一样的输出。
var
myBool = true
myCharacter = 'n'
myString = "nim"
myInteger = 42
myFloat = 3.14
echo($myBool, ":", repr(myBool))
# --> true:true
echo($myCharacter, ":", repr(myCharacter))
# --> n:'n'
echo($myString, ":", repr(myString))
# --> nim:0x10fa8c050"nim"
echo($myInteger, ":", repr(myInteger))
# --> 42:42
echo($myFloat, ":", repr(myFloat))
# --> 3.1400000000000001e+00:3.1400000000000001e+00