将变量传递给过程与使用 upvar?

问题描述 投票:0回答:1

使用

upvar
是否有成本,因此只有当目标是让过程在其“上方”的上下文中设置变量值时才应该使用它?并且不使用它来代替传递使用该值但不需要将其设置在其自身上下文之外的参数?

我正在转向 Tcl 的代码中有几个实例,其中将参数传递给函数,然后该函数将其传递给另一个函数,但在其他情况下不使用它。在 Tcl 中,

upvar 2
可以根本不传递变量,但我想知道这涉及多少工作,以及我是否应该匹配与大多数语言的函数中使用的相同的传递方案。

感谢您考虑我的问题。

tcl
1个回答
0
投票

性能不是问题。语义是问题。

理论上

upvar
应该比传入值有更好的性能。这是因为使用
upvar
,您只需传递变量的名称,然后指向该值 - 本质上类似于在其他语言中传递指针/引用。

实际上,这几乎没有什么区别,因为 tcl 不会复制不必要的值。 tcl 在内部实现写时复制并且仅传递指针。仅当您尝试写入某个值时,Tcl 才会执行该值的完整复制。

语义

语义是最大的区别。

许多更新的现代编程语言引入了可变性的概念,主要受到纯函数式语言的启发,在纯函数式语言中,变量在第一次赋值后不能更改值。例如,Java 和 Typescript 等语言引入了

final
const
关键字来使变量不可变。像 Rust 这样的语言默认情况下变量是不可变的,并引入了
mut
关键字来使选定的变量可变。

然而,tcl 的另一种机制在其他语言中经常被忽视:变量的更改始终是local。也就是说,如果您修改参数

x
,它不会影响其在调用者范围内的值。这是全局不变性但局部可变性(我可以发誓有一个名称,但现在想不起来,无论如何,Tcl 社区从未直接为该功能命名)。

我相信 Apple 的 Swift 也有类似的功能,但实现方式略有不同。在 Tcl 中,它只是 everything-is-a-string(一切都是值)的副作用。拥有这种严格的复制语义使 Tcl 有时感觉非常实用,并且对于管理代码复杂性和提高代码清晰度非常有帮助。

Upvar
是 tcl 的逃逸阀,当您需要可变性来感染调用者的范围时。因此,明智的做法是仅在需要该变量的可变性来感染调用者作用域的情况下使用它(如果您需要该函数来修改调用者作用域中的变量)。

就我个人而言,我在通常需要 C/C++ 指针的地方使用

upvar

© www.soinside.com 2019 - 2024. All rights reserved.