2025年4月12日 星期六 乙巳(蛇)年 正月十三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Lua

或许这只是 LUA 的一种惯用法而已

时间:12-14来源:作者:点击数:6
CDSY,CDSY.XYZ

同事指着一份源码问我,老黄,你知道他们为什么要这么写代码么,我瞅过去,看到了如下代码:

  • local get_upstream_by_id
  • do
  • ------------------------------------------------------------------------------
  • -- Loads a single upstream entity.
  • -- @param upstream_id string
  • -- @return the upstream table, or nil+error
  • local function load_upstream_into_memory(upstream_id)
  • log(DEBUG, "fetching upstream: ", tostring(upstream_id))
  • local upstream, err = singletons.db.upstreams:select({id = upstream_id})
  • if not upstream then
  • return nil, err
  • end
  • return upstream
  • end
  • _load_upstream_into_memory = load_upstream_into_memory
  • get_upstream_by_id = function(upstream_id)
  • local upstream_cache_key = "balancer:upstreams:" .. upstream_id
  • return singletons.cache:get(upstream_cache_key, nil,
  • load_upstream_into_memory, upstream_id)
  • end
  • end

他迷惑的是,为啥要写成这种 local xx do ... end 的格式。而且就上面这段代码来说,完全可以直接写成这样:

  • ------------------------------------------------------------------------------
  • -- Loads a single upstream entity.
  • -- @param upstream_id string
  • -- @return the upstream table, or nil+error
  • local function load_upstream_into_memory(upstream_id)
  • log(DEBUG, "fetching upstream: ", tostring(upstream_id))
  • local upstream, err = singletons.db.upstreams:select({id = upstream_id})
  • if not upstream then
  • return nil, err
  • end
  • return upstream
  • end
  • _load_upstream_into_memory = load_upstream_into_memory
  • local get_upstream_by_id = function(upstream_id)
  • local upstream_cache_key = "balancer:upstreams:" .. upstream_id
  • return singletons.cache:get(upstream_cache_key, nil,
  • load_upstream_into_memory, upstream_id)
  • end

前后两段从语义上并无二致。

因为单从 lua 的 do end 语法来看,do end 只是限定了本地变量的作用域,do end 内部定义的 local 变量,出了作用域就无法直接访问了(除了被闭包引用之外)。

从网络搜索,也基本印证这种说法:

问题是,刚开始的那段代码中的 do end 块中,并没有定义 local 变量啊,为啥还要这么写呢,我想,估计作者就是喜欢按照这个套路来,或者最早的代码中在do end中有local变量,或者后续代码功能增强或者重构后,也可能产生新的 local 变量,这样子 do end 的代码结构还可以保持不变。例如

  • local get_upstream_by_id
  • do
  • local xx
  • local yy
  • -- ...
  • end

只能说作者学了 do end 的一招鲜了,不管是不是有用,都套上一把。跟那种写JAVA,有的同学总是在方法开头声明所有变量一样,有点相同的意味。

We can delimit a block explicitly, bracketing it with the keywords do-end. These do blocks can be useful when you need finer control over the scope of one or more local variables:

  • do
  • local a2 = 2*a
  • local d = sqrt(b^2 - 4*a*c)
  • x1 = (-b + d)/a2
  • x2 = (-b - d)/a2
  • end -- scope of `a2' and `d' ends here
  • print(x1, x2)

At times it is useful to further limit the scope of local variables with do-blocks [PIL 4.2]:

  • local v
  • do
  • local x = u2*v3-u3*v2
  • local y = u3*v1-u1*v3
  • local z = u1*v2-u2*v1
  • v = {x,y,z}
  • end
  • local count
  • do
  • local x = 0
  • count = function() x = x + 1; return x end
  • end

Global variables scope can be reduced as well via the Lua module system [PIL2 15] or [setfenv].

CDSY,CDSY.XYZ
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐