【问题标题】:What exactly are strings in Nim?Nim 中的字符串到底是什么?
【发布时间】:2015-04-01 20:15:51
【问题描述】:

据我了解,Nim 中的字符串基本上是可变的字节序列,它们在赋值时被复制。

鉴于此,我假设 sizeof 会告诉我(如 len)字节数,但它总是在我的 64 位机器上给出 8,所以它似乎持有一个指针。

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

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

  • 是否有过分配时不复制的情况? (我假设非var 函数参数不会复制。还有其他吗?)

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

  • 字符串和序列之间是否有任何显着差异,或者上述问题的答案是否可以平等地应用于所有序列?

  • 一般还有什么值得注意的吗?

谢谢!

【问题讨论】:

  • 为了完整起见,nim 字符串定义存在于on github,这可能有助于解释它为什么报告它所报告的内容。
  • @Mike'Pomax'Kamermans:谢谢你的链接,但我不知道string* {.magic: String.} 想告诉我什么。 ;-)
  • 是的,我自己也不太确定,只是认为在这个问题中提供的信息可能是一个很好的信息,可以帮助人们比我们更善于发现最新情况=)
  • 啊,我明白你的意思了。 :-)

标签: string nim-lang


【解决方案1】:

字符串的定义其实在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

因此,字符串是指向具有lenreserveddata 字段的对象的原始指针。字符串的过程在sysstr.nim 中定义。

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

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

var s = "foo"
shallow s

【讨论】:

  • 谢谢def-。这很有帮助,看来shallow 会很有用。
  • 除了shallow 为所有未来的副本启用“作为指针复制”行为,还有一个shallowCopy 操作只能在特定的地方使用。在底层,以这种方式管理的 sting 将共享相同的 ref-counted 内存分配。
猜你喜欢
  • 1970-01-01
  • 2011-01-06
  • 2022-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
相关资源
最近更新 更多