点击“阅读原文”,可以查看 GitHub 上的原文。

  • 缩进

在 OpenResty 中使用 4 个空格作为缩进的标记,虽然 Lua 并没有这样的语法要求。

--No

if a then

ngx.say("hello")

end


--yes

if a then

ngx.say("hello")

end

你可以在使用的编辑器中,把 tab 改为 4 个空格,来简化操作。

  • 空格

在操作符的两边,都需要用一个空格来做分隔:

--No

local i=1

local s = "apisix"


--Yes

local i = 1

local s = "apisix"

  • 空行

不少开发者会把其他语言的开发习惯带到 OpenResty 中来,比如在行尾增加一个分号。

--No

if a then

ngx.say("hello");

end;

增加分号会让 Lua 代码显得非常丑陋,也是没有必要的。另外,不要为了节省代码的行数,后者为了显得“简洁”,而把多行代码变为一行。这样会在定位错误的时候不知道到底那一段代码出了问题:

--No

if a then ngx.say("hello") end


--yes

if a then

ngx.say("hello")

end

函数之间需要用两个空行来做分隔:

--No

local function foo()

end

local function bar()

end


--Yes

local function foo()

end



local function bar()

end

如果有多个 if elseif 的分支,它们之间需要一个空行来做分隔:

--No

if a == 1 then

foo()

elseif a== 2 then

bar()

elseif a == 3 then

run()

else

error()

end


--Yes

if a == 1 then

foo()


elseif a== 2 then

bar()


elseif a == 3 then

run()


else

error()

end

  • 每行最大长度

每行不能超过 80 个字符,超过的话,需要换行并对齐:

--No

return limit_conn_new("plugin-limit-conn", conf.conn, conf.burst, conf.default_conn_delay)


--Yes

return limit_conn_new("plugin-limit-conn", conf.conn, conf.burst,

conf.default_conn_delay)

在换行对齐的时候,要体现出上下两行的对应关系。就上面的示例而言,第二行函数的参数,要在第一行左括号的右边。

如果是字符串拼接的对齐,需要把 .. 放到下一行中:

<span>--No</span>

<span><span>return</span> limit_conn_new(<span>&quot;plugin-limit-conn&quot;</span> .. <span>&quot;plugin-limit-conn&quot;</span> ..</span>

<span> <span>&quot;plugin-limit-conn&quot;</span>)</span>

<span></span>

<span>--Yes</span>

<span><span>return</span> limit_conn_new(<span>&quot;plugin-limit-conn&quot;</span> .. <span>&quot;plugin-limit-conn&quot;</span></span>

<span> .. <span>&quot;plugin-limit-conn&quot;</span>)</span>

  • 变量

应该永远使用局部变量,不要使用全局变量:

--No

i = 1

s = "apisix"


--Yes

local i = 1

local s = "apisix"

变量命名使用 snake_case 风格:

--No

local IndexArr = 1

local str_Name = "apisix"


--Yes

local index_arr = 1

local str_name = "apisix"

对于常量要使用全部大写:


--No

local max_int = 65535

local server_name = "apisix"


--Yes

local MAX_INT = 65535

local SERVER_NAME = "apisix"

  • 数组

使用 table.new 来预先分配数组:

--No

local t = {}

for i = 1, 100 do

t[i] = i

end


--Yes

local new_tab = require "table.new"

local t = new_tab(100, 0)

for i = 1, 100 do

t[i] = i

end

不要在数组中使用 nil :

--No

local t = {1, 2, nil, 3}

如果一定要使用空值,请用 ngx.null 来表示:

--No

local t = {1, 2, ngx.null, 3}

  • 字符串

不要在热代码路径上拼接字符串:

--No

local s = ""

for i = 1, 100000 do

s = s .. "a"

end


--Yes

local t = {}

for i = 1, 100000 do

t[i] = "a"

end

local s = table.concat(t, "")

  • 函数

函数的命名也同样遵循 snake_case :

--No

local function testNginx()

end


--Yes

local function test_nginx()

end

函数应该尽可能早的返回:

--No

local function check(age, name)

local ret = true

if age < 20 then

ret = false

end


if name == "a" then

ret = false

end

-- do something else

return ret

end


--Yes

local function check(age, name)

if age < 20 then

return false

end


if name == "a" then

return false

end

-- do something else

return true

end

  • 模块

所有 require 的库都要 local 化:

--No

local function foo()

local ok, err = ngx.timer.at(delay, handler)

end


--Yes

local timer_at = ngx.timer.at


local function foo()

local ok, err = timer_at(delay, handler)

end

为了风格的统一,require 和 ngx 也需要 local 化:

--No

local core = require("apisix.core")

local timer_at = ngx.timer.at


local function foo()

local ok, err = timer_at(delay, handler)

end


--Yes

local ngx = ngx

local require = require

local core = require("apisix.core")

local timer_at = ngx.timer.at


local function foo()

local ok, err = timer_at(delay, handler)

end

  • 错误处理

对于有错误信息返回的函数,必须对错误信息进行判断和处理:

--No

local sock = ngx.socket.tcp()

local ok = sock:connect("www.google.com", 80)

ngx.say("successfully connected to google!")


--Yes

local sock = ngx.socket.tcp()

local ok, err = sock:connect("www.google.com", 80)

if not ok then

ngx.say("failed to connect to google: ", err)

return

end

ngx.say("successfully connected to google!")

自己编写的函数,错误信息要作为第二个参数,用字符串的格式返回:

--No

local function foo()

local ok, err = func()

if not ok then

return false

end

return true

end


--No

local function foo()

local ok, err = func()

if not ok then

return false, {msg = err}

end

return true

end


--Yes

local function foo()

local ok, err = func()

if not ok then

return false, "failed to call func(): " .. err

end

return true

end

相关文章