String Nim中的字符串到底是什么?
据我所知,Nim中的字符串基本上是一个可变的字节序列,它们是在赋值时复制的 考虑到这一点,我假设String Nim中的字符串到底是什么?,string,nim-lang,String,Nim Lang,据我所知,Nim中的字符串基本上是一个可变的字节序列,它们是在赋值时复制的 考虑到这一点,我假设sizeof会告诉我(比如len)字节数,但在我的64位机器上它总是给出8,所以它似乎持有一个指针 鉴于此,我有以下问题 在任务中复制的动机是什么?是因为它们是可变的吗 是否有一段时间分配时不复制?(我假设非var函数参数不复制。还有其他吗?) 它们是否经过优化,只有在发生变异时才会被复制 字符串和序列之间是否存在显著差异,或者上述问题的答案是否可以同样适用于所有序列 还有什么值得注意的吗 谢谢大
sizeof
会告诉我(比如len
)字节数,但在我的64位机器上它总是给出8
,所以它似乎持有一个指针
鉴于此,我有以下问题
- 在任务中复制的动机是什么?是因为它们是可变的吗
- 是否有一段时间分配时不复制?(我假设非
函数参数不复制。还有其他吗?)var
- 它们是否经过优化,只有在发生变异时才会被复制
- 字符串和序列之间是否存在显著差异,或者上述问题的答案是否可以同样适用于所有序列
- 还有什么值得注意的吗
谢谢大家! 字符串的定义实际上在
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
、保留
和数据
字段的对象的原始指针。字符串的过程在中定义
默认情况下,字符串赋值的语义与Nim中所有值类型(不是ref或ptr)的语义相同,因此可以假设赋值创建了一个副本。当副本不必要时,编译器可以省略它,但我不确定到目前为止发生了多少。将字符串传递到proc不会复制它们。没有任何优化可以阻止字符串复制,直到它们发生变异。序列的行为方式相同
您可以通过将字符串和序列标记为浅字符串来更改它们的默认赋值行为,然后在赋值时不进行复制:
var s = "foo"
shallow s
为了完整性,nim字符串定义仍然有效,这可能有助于解释为什么它会报告它报告的内容。@Mike'Pomax'Kamermans:谢谢你的链接,但我不知道
string*{.magic:string.}
试图告诉我什么。;-)是的,我自己也不太确定,只是觉得这可能是一个很好的信息,可以作为比我们更善于发现问题的人的潜在线索=)啊,我明白你的意思了。:-)谢谢。这非常有帮助,而且似乎shallow
将非常有用。除了shallow
为所有将来的副本启用“复制为指针”行为之外,还有一个shallowCopy
操作,只能在特定位置使用。在引擎盖下,以这种方式管理的stings将共享相同的ref计数内存分配。