Nim中究竟是什么字符串?

Lye*_*ish 8 string nim-lang

根据我的理解,Nim中的字符串基本上是一个可变的字节序列,并且它们在赋值时被复制.

鉴于此,我认为这sizeof会告诉我(比如len)字节数,但它总是8在我的64位机器上给出,所以它似乎拿着一个指针.

鉴于此,我有以下问题......

  • 复制作业背后的动机是什么?是因为它们是可变的吗?

  • 有没有时间分配时不复制?(我假设非var功能参数不复制.还有别的吗?)

  • 它们是否经过优化,只有当它们发生变异时才真正被复制?

  • 字符串和序列之间是否有任何显着差异,或者上述问题的答案是否同样适用于所有序列?

  • 还有什么其他值得注意的吗?

谢谢!

def*_*ef- 10

字符串的定义实际上是在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
Run Code Online (Sandbox Code Playgroud)

因此,一个字符串是一个原始指针与一个对象len,reserveddata现场.字符串的procs在sysstr.nim中定义.

默认情况下,字符串赋值的语义被选择为与Nim中的所有值类型(不是ref或ptr)相同,因此您可以假设赋值创建副本.当一个副本是不必要的时,编译器可以将其删除,但我不确定到目前为止发生了多少.将字符串传递给proc不会复制它们.没有优化可以阻止字符串副本,直到它们发生变异.序列的行为方式相同.

您可以通过将字符串和seq标记为浅层来更改它们的默认赋值行为,然后在赋值时不会复制:

var s = "foo"
shallow s
Run Code Online (Sandbox Code Playgroud)

  • 除了``shallow``,它可以为所有未来的副本提供"copy as pointer"行为,还有一个``shallowCopy``操作,只能在特定的地方使用.在引擎盖下,以这种方式管理的stings将共享相同的ref-counting内存分配. (2认同)