我正在努力决定Nim的政策背后expression has no address.特别是,我有一个C函数,它接受一些数据缓冲区的指针(+长度等).我知道这个函数不会修改数据.简化:
type
Buffer = object
data: seq[float]
proc wrapperForCCall(buf: Buffer) =
# accessing either buf.addr nor buf.data.addr produces
# Error: expression has no address
# workaround:
var tmp = buf.data # costly copy
callToC(tmp.len, tmp.addr) # now it works
Run Code Online (Sandbox Code Playgroud)
一方面这是有道理的,因为一个参数看起来就像一个let绑定,它也"没有地址".另一方面,我对手册中的这句话感到困惑:
var参数对于有效的参数传递永远不是必需的.
据我所知,避免复制数据的唯一方法是:
buf: var Bufferref object.在这两种情况下,这表明我的函数修改了数据.此外,它在调用者站点上引入了可变性(即用户不能再使用let绑定它们的缓冲区).对我来说,关键的问题是:既然"我知道" callToC是只读的,我可以说服Nim在没有副本的情况下允许两种不变性吗?我发现这是危险的,因为我必须确定呼叫是不可变的.因此,这需要某种"不安全的地址"机制,允许强制指向不可变数据?
我最后的参数地址之谜:我试图通过将类型更改为显式来明确复制的必要性Buffer {.bycopy.} = object.在这种情况下,副本已经在呼叫时发生,我希望现在可以访问该地址.为什么在这种情况下拒绝访问?