用 do-end 整理你的代码

do-end 代码块主要是解决变量作用域问题。例如,下面这个示例代码将输出什么呢?

local x = 10
if x > 0 then
    local x = 17
    print(x)    -- output: 17
end
print(x)        -- output: 10

这里出现的本地变量,Lua 使用标准词法作用域,所以这里 lua 的变量可以按照思维习惯输出。这么做有下面几个原因:

  • 变量作用域是静态的。你可以通过查看源代码,就能知晓什么变量和函数对应这代码中的每个标识。
  • 变量范围有限,这有助于可读性,并避免一些错误。
  • 避免命名冲突。
  • 访问局部变量的速度比全局变量更快。
local i = 8

do
  local a = i
  x1 = a + 1
end         -- scope of `a` ends here
print(x1)   -- output: 9
print(a)    -- output: nil

没有 do-end 块,输出的结果就不一样了。

local i = 8

local a = i
x1 = a + 1
print(x1)   -- output: 9
print(a)    -- output: 8

这里做一些有趣的尝试,对于隐藏变量,看下面三个示例:

-- 本地变量外部函数
local func
do
  local a = 0
  func = function(inc)
    a = a + inc
    return a
  end
end

print(func(1))  -- output: 1
print(func(2))  -- output: 3
print(func(3))  -- output: 6
-- 全局函数
do
  local a = 0
  function func(inc)
    a = a + inc
    return a
  end
end

print(func(1))  -- output: 1
print(func(2))  -- output: 3
print(func(3))  -- output: 6
-- 方法
local tbl = {}
do
  local a = 0
  function tbl.func(self, inc)
    a = a + inc
    return a
  end
end

print(tbl:func(1))  -- output: 1
print(tbl:func(2))  -- output: 3
print(tbl:func(3))  -- output: 6

那么哪一种更好呢?如果只从 Lua 语言角度看,貌似已经有点难做出选择。但是考虑不同开发语言之间的通用,这三个风格都不足够通用。 所以这里笔者更推荐下面的方式实现上面的逻辑。

-- 类方式
local tbl = { a = 0 }

function tbl.func(self, inc)
    self.a = self.a + inc
    return self.a
end

print(tbl:func(1))  -- output: 1
print(tbl:func(2))  -- output: 3
print(tbl:func(3))  -- output: 6

results matching ""

    No results matching ""