为什么在 Nim 中引用不可变变量不是没有副作用的?

Why referring to immutable variable is NOT side effect free in Nim?

由于引用了 let one = 1.

,下面的代码无法编译

为什么?它似乎没有副作用(而且线程安全)——因为不可能更改不可变数据。

playground

let one = 1
func one_plus(v: int): int =
  one + v
  
echo one_plus(2)

像这样的代码 - 指的是外部不可变数据 - 应该在 Nim 中以某种不同的方式编写才能被认为是无副作用的吗?

我的猜测是问题出在使用全局命名空间,将您的代码包装到一个 proc 中使其编译并且 运行:

proc main() =
  let one = 1
  func one_plus(v: int): int =
    one + v
    
  echo one_plus(2)

main()

如果你还想使用全局,你需要使用const section:

const one = 1
func one_plus(v: int): int =
  one + v
  
echo one_plus(2)

即使变量是不可变的,也不一定意味着它没有副作用。

考虑这个例子:

type A = ref object
  i: int

let one = A(i: 2)
proc one_plus(v: int): int =
  one.i += v
  one.i

echo one.i
echo one_plus(2)
echo one.i

https://play.nim-lang.org/#ix=3zRB

输出:

2
4
4

let oneref 指针存储到内存地址,您无法更改它(指针)。但是在取消引用之后,我可以更改底层对象的数据,即使变量被声明为 let.