Lua 中是否应该使用参数作为变量?

Should parameters be used as variables in Lua?

我在 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

也是望而却步,还是好看又简洁?

如果您被告知不要修改函数的参数,那么可能有一个与之相关的推理。无论该推理是什么,都适用于 Lua 和 Java,因为它们具有相似的函数参数语义。这些原因可能是以下一项或多项(但不限于):

  • 如果你修改了一个参数...你就没有了。如果您突然需要传递给您的原始值,它现在已经消失了。

  • 造成混淆,具体取决于参数的命名方式。 "begin" 表示某事的开始。如果你改变它,它不再是开始,而只是你正在操作的当前元素。

  • 如果处理引用类型([=29= 中的非基本类型],Lua 中的表等),则会产生潜在的错误。当您修改一个对象时,您是在为每个人更改它。而递增整数只是更改您的本地值。所以如果你经常修改参数,你仍然需要考虑哪些你应该戳,哪些你不应该。

换句话说,如果您同意 Java 中的建议,那么它同样适用于 Lua。如果您不同意 Java 中的建议,那么您没有更多理由在 Lua 中遵循它。

没有规则。让品味、清晰度和需求来决定。

尽管如此,一个常见的习惯用法是为参数提供默认值,如

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

在Lua函数中,线程、表和用户数据类型通过引用传递。因此,除非您拥有其中之一,否则您无论如何都在使用本地副本。

所以在你的例子中:

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

beginlastdo_stuff 范围内的局部非引用变量。

复制它们的唯一原因是您可能希望将初始值存储在那里供以后使用。为此,您可以创建初始值的备份副本或创建它的工作副本。随心所欲。

只确保你知道什么是通过引用传递的,什么是通过值传递的,这样你就可以避免更改你不想更改的内容,反之亦然。