Nim 中的字符串到底是什么?
What exactly are strings in Nim?
据我了解,Nim 中的字符串基本上是一个可变的字节序列,它们在赋值时被复制。
鉴于此,我假设 sizeof
会告诉我(如 len
)字节数,但在我的 64 位机器上它总是给出 8
,所以好像拿着指针。
鉴于此,我有以下问题...
copy on assignment 背后的动机是什么?是因为它们是可变的吗?
有没有在分配时没有复制的时候? (我假设非 var
函数参数不会复制。还有什么吗?)
它们是否经过优化,以至于它们实际上只被复制if/when它们发生了变异?
字符串和序列之间是否存在显着差异,或者上述问题的答案是否可以同样适用于所有序列?
一般还有什么值得注意的吗?
谢谢!
字符串的定义实际上在system.nim
中,只是在另一个名字下:
type
TGenericSeq {.compilerproc, pure, inheritable.} = object
len, reserved: int
PGenericSeq {.exportc.} = ptr TGenericSeq
UncheckedCharArray {.unchecked.} = array[0..ArrayDummySize, char]
# len and space without counting the terminating zero:
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
data: UncheckedCharArray
NimString = ptr NimStringDesc
因此,字符串是指向具有 len
、reserved
和 data
字段的对象的原始指针。字符串的过程在 sysstr.nim.
中定义
默认情况下,字符串赋值的语义已被选择为与 Nim 中所有值类型(不是 ref 或 ptr)相同,因此您可以假设赋值创建一个副本。当不需要副本时,编译器可以将其忽略,但我不确定到目前为止发生了多少。将字符串传递给 proc 不会复制它们。没有优化可以防止字符串复制,直到它们发生变化。序列的行为方式相同。
您可以更改字符串和序列的默认赋值行为,方法是将它们标记为浅表,然后在赋值时不进行任何复制:
var s = "foo"
shallow s
据我了解,Nim 中的字符串基本上是一个可变的字节序列,它们在赋值时被复制。
鉴于此,我假设 sizeof
会告诉我(如 len
)字节数,但在我的 64 位机器上它总是给出 8
,所以好像拿着指针。
鉴于此,我有以下问题...
copy on assignment 背后的动机是什么?是因为它们是可变的吗?
有没有在分配时没有复制的时候? (我假设非
var
函数参数不会复制。还有什么吗?)它们是否经过优化,以至于它们实际上只被复制if/when它们发生了变异?
字符串和序列之间是否存在显着差异,或者上述问题的答案是否可以同样适用于所有序列?
一般还有什么值得注意的吗?
谢谢!
字符串的定义实际上在system.nim
中,只是在另一个名字下:
type
TGenericSeq {.compilerproc, pure, inheritable.} = object
len, reserved: int
PGenericSeq {.exportc.} = ptr TGenericSeq
UncheckedCharArray {.unchecked.} = array[0..ArrayDummySize, char]
# len and space without counting the terminating zero:
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
data: UncheckedCharArray
NimString = ptr NimStringDesc
因此,字符串是指向具有 len
、reserved
和 data
字段的对象的原始指针。字符串的过程在 sysstr.nim.
默认情况下,字符串赋值的语义已被选择为与 Nim 中所有值类型(不是 ref 或 ptr)相同,因此您可以假设赋值创建一个副本。当不需要副本时,编译器可以将其忽略,但我不确定到目前为止发生了多少。将字符串传递给 proc 不会复制它们。没有优化可以防止字符串复制,直到它们发生变化。序列的行为方式相同。
您可以更改字符串和序列的默认赋值行为,方法是将它们标记为浅表,然后在赋值时不进行任何复制:
var s = "foo"
shallow s