【Nim】基本数据类型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aqtata/article/details/82585230

1、整数类型

有符号的

echo sizeof(int)     # 取决于系统和编译器,一般是4
echo sizeof(int8)    # size = 1
echo sizeof(int16)   # size = 2
echo sizeof(int32)   # size = 4
echo sizeof(int64)   # size = 8

proc foo1(x: int64) =
    echo x

# 接受任意有符号整数,同等于"int|int8|int16|int32|int64",比直接指定int64更语义化
proc foo2(x: SomeSignedInt) =
    echo x

foo1(888i64)
foo2(888i64)

无符号的

echo sizeof(uint)     # 取决于系统和编译器,一般是4
echo sizeof(uint8)    # size = 1
echo sizeof(uint16)   # size = 2
echo sizeof(uint32)   # size = 4
echo sizeof(uint64)   # size = 8

proc foo1(x: uint64) =
    echo x

# 接受任意无符号整数,同等于"uint|uint8|uint16|uint32|uint64",比直接指定uint64更语义化
proc foo2(x: SomeUnsignedInt) =
    echo x

foo1(888u64)
foo2(888u64)

如果打算接受有符号和无符号的,可以用SomeInteger

# 接受任意整数类型,同等于"SomeSignedInt|SomeUnsignedInt"
proc foo(x: SomeInteger) =
    echo x

foo(888i64)
foo(888u64)

2、浮点类型

echo sizeof(float)   # 取决于系统和编译器,一般是8
echo sizeof(float32) # size = 4
echo sizeof(float64) # size = 8
 
# 接受任意浮点类型,同等于"float|float32|float64"
proc foo(x: SomeReal) =
    echo x
 
foo(3.14f)
foo(3.14f32)
foo(3.14f64)
foo(2e2)

如果可以接受任何数字类型,可以用SomeNumber

# 接受任意数字类型,同等于"SomeInteger|SomeReal"
proc foo(x: SomeNumber) =
    echo x

foo(666)
foo(3.14f)
foo(888u64)

二、布尔值

var b: bool

echo sizeof(b)  # size = 1

echo b # 默认值为false

b = on  # true的别名
echo b  # true

b = off # false的别名
echo b  # false

# bool本质上是枚举类型,只可以赋值0或1
b = bool(0)
echo b  # 0 = false

b = bool(1)
echo b  # 1 = true

# 编译错误
#b = bool(2)

三、字符

echo sizeof(char) # size = 1,本质上是uint8类型

var c: char = 'a'
echo c
echo ord(c)  # 97,ord方法得到字符的ascii码
echo chr(98) # 'b',chr方法将数字转换为字符

var s: string = $c # 将char类型赋值给string类型必须在前面加上美元符号
echo s

四、字符串

var s: string

# 未赋值时是nil
if s == nil:
    echo "s == nil"

s = "hello"
echo len(s)    # len = 5
echo s[0]      # 'h'
echo ord(s[5]) # string以'\0'字符结束

s.add(" 世")   # 用add方法在末尾追加字符串
s &= "界"      # 字符串之间用'&'符号连接
echo s         # hello 世界

严格来讲,Nim并没有Python、C#那样真正的字符串,而是和C/C++中string一样,其本质就是array[char]类型,在Nim中应该表示为seq[char]。所以string硬编码字符串的编码格式取决于源文件编码,一般是utf8

var s = "hello"
echo s.addr.repr

var s2 = s
echo s2.addr.repr

输出:

ref 0042BD1C --> 0095A030"hello"

ref 0042BD14 --> 0095A048"hello"

可见内存地址不同,所以在Nim这里,不像Python、C#那样有不可变数据的说法。

字符串之间的赋值就等同于是数组的完整拷贝,这么做是非常低效的,一定要注意。

如果需要使用引用,可以试试shallowCopy方法

proc foo() =
  var s = "hello"
  var s2: string
  var s3: string
  
  shallowCopy(s2, s)
  shallowCopy(s3, s2)

  echo s.addr.repr
  echo s2.addr.repr
  echo s3.addr.repr

foo()

这样3个字符串都指向同一内存了,还可以这样用

proc foo() =
  var s = "hello"
  s.shallow # 调用之后,赋值操作将会变为传递引用

  var s2 = s
  var s3 = s2

  echo s.addr.repr
  echo s2.addr.repr
  echo s3.addr.repr

foo()

但shallow也有副作用,编译器在某些情况下可能会忽略掉它,比如全局变量

var s = "hello"
s.shallow

var s2 = s
var s3 = s2

echo s.addr.repr
echo s2.addr.repr
echo s3.addr.repr

同样的代码,从foo函数中挪到全局中,结果三个字符串的地址还是不同

再或者源字符串发生变化,后面的引用的变量是感知不到的

var s = "hello"
s.shallow
 
var s2 = s
var s3 = s2
 
echo s.repr
echo s2.repr
echo s3.repr

s.add("world")

echo s.repr
echo s2.repr
echo s3.repr

所以shallow也并非是完美的办法,期待Nim在以后的版本中能提供像Python那样不可变的string。

最后,多行字符串用三个双引号括起来

var
    s = """line1
line2
line3"""

echo s

参考:

https://nim-lang.org/docs/tut1.html#basic-types

猜你喜欢

转载自blog.csdn.net/aqtata/article/details/82585230