在Lua中,应该将参数用作变量吗?

3

在Java中,我被告知应避免修改原始参数,例如

public int doStuff(int begin, int end) {
  /* loop or something */
  begin++; //bad
  end--; //also bad
  /* end loop */
  return
}

相反,我应该做类似于以下的操作
public int doStuff(int begin, int end) {
  int myBegin = begin; //something like this
  int myEnd = end;
  /* stuff */
  return
}

所以,我一直在使用lua做这个

function do_stuff(begin, last)
  local my_begin = begin
  local my_last = last
  --stuff
  my_begin = my_begin + 1
  my_last = my_last - 1
  --stuff
end

但是,我在想是否

function do_stuff(begin, last)
  --stuff
  begin = begin + 1
  last = last - 1
  --stuff
end
不推荐使用这种写法,还是简短明了为好吗?

2
这很好而且简洁。 - Egor Skriptunoff
3个回答

6

没有固定的规则,取决于口感、清晰度和需要。

然而,一个常见的习语是在参数中提供默认值,例如:

function log(x,b)
   b = b or 10
   ...
end

2
如果有人告诉你不要修改函数的参数,那么这可能是有原因的。无论是Lua还是Java,它们都具有类似的函数参数语义,所以这个原因同样适用于它们。这些原因可能包括(但不限于):
- 如果您修改了一个参数,那么您就不再拥有它了。如果您突然需要使用传递给您的原始值,那么它已经不存在了。 - 根据参数的命名方式会产生混淆。例如,单词"begin"表示某物的开端。如果您更改了它,它不一定是开始了,而只是您正在操作的当前元素。 - 如果处理引用类型(Java中的非基本类型,Lua中的表等),则会创建潜在的错误。当您修改一个对象时,您正在为所有人进行更改。而增加整数只是改变了您的本地值。因此,如果您经常修改参数,则仍然需要考虑哪些参数应该被更改,哪些不应该被更改。
换句话说,如果您同意在Java中这样做,那么它同样适用于Lua。如果您不同意在Java中这样做,那么您没有理由在Lua中遵循该建议。

“如果你改变它,那么它就不再是开始了。”的确如此!我几乎在任何地方都避免使用变量的概念。如果您更改变量的值,则如果其名称起初被正确命名,则其名称应成为谎言。但是,对于参数,像@lhf建议的立即、短暂、明智的“修复”(例如默认值)可能会有用。 - Tom Blodget

1
在Lua函数中,线程、表和用户数据类型是通过引用传递的。因此,除非你正在处理其中之一,否则你正在使用本地副本。所以在你的例子中:
function do_stuff(begin, last)
  --stuff
  begin = begin + 1
  last = last - 1
  --stuff
end

beginlast是在do_stuff范围内的本地非引用变量。

复制它们的唯一原因是您可能想要存储其初始值以供将来使用。为此,您可以创建初始值的备份副本或创建工作副本。无论您喜欢哪种方式。

只需确保您知道通过引用传递了什么以及通过值传递了什么,以便避免更改您不想更改的内容以及反之。


在计算机科学的历史术语中,所有的Lua参数都是通过“按值传递”的方式传递的。在SO上,变量不能通过实际参数进行引用。(从语法上讲,实际参数始终是表达式,无论多么简单,表达式都不能被赋予新值。) - Tom Blodget

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接