为什么在 Nim 中引用不可变变量不是没有副作用的?
Why referring to immutable variable is NOT side effect free in Nim?
由于引用了 let one = 1
.
,下面的代码无法编译
为什么?它似乎没有副作用(而且线程安全)——因为不可能更改不可变数据。
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 one
将 ref
指针存储到内存地址,您无法更改它(指针)。但是在取消引用之后,我可以更改底层对象的数据,即使变量被声明为 let
.
由于引用了 let one = 1
.
为什么?它似乎没有副作用(而且线程安全)——因为不可能更改不可变数据。
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 one
将 ref
指针存储到内存地址,您无法更改它(指针)。但是在取消引用之后,我可以更改底层对象的数据,即使变量被声明为 let
.