OpenResty Best Practices-Lua Basic Data Type

Posted by

Lua Basic Data Type

The function type can return a value or the type to which a variable belongs.

print(type("hello world")) -->output:string
print(type(print))         -->output:function
print(type(true))          -->output:boolean
print(type(360.0))         -->output:number
print(type(nil))           -->output:nil


Nil is a type, and Lua uses nil to denote “invalid values”. The default value of a variable before the first assignment is nil. Giving nil to a global variable is equivalent to deleting it.

local num
print(num)        -->output:nil

num = 100
print(num)        -->output:100

It is worth mentioning that OpenResty’s UA interface also provides a special null value, ngx. null, which is used to represent “null values” different from nil. Later, when we discuss OpenResty’s EDIS library, we will encounter it.


Boolean type, optional value true/false; nil and false in Lua are “false” and all other values are “true”. For example, 0 and empty strings are “true”; C or Perl programmers may be surprised at that.

local a = true
local b = 0
local c = nil
if a then
    print("a")        -->output:a
    print("not a")    --not exec

if b then
    print("b")        -->output:b
    print("not b")    --not exec

if c then
    print("c")        --not exec
    print("not c")    -->output:not c


Number type is used to represent real numbers, similar to the double type in C/C++. Math. floor and math. ceil can be used to perform integer operations.

local order = 3.99
local score = 98.01
print(math.floor(order))   -->output:3
print(math.ceil(score))    -->output:99

Generally, Lua’s number type is implemented with double-precision floating-point numbers. It is worth mentioning that LuaJIT supports the so-called “dual-number” mode, in which LuaJIT stores integers in context and floating-point numbers in double-precision floating-point numbers.

In addition, LuaJIT supports large integers of “long integers” (64-bit integers on the x86_64 architecture). for example


There are three ways to represent strings in Lua:

  1. Use a pair of matched single quotes. Example:’hello’.
  2. Use a pair of matched double quotes. Example: “abclua”.
  3. Strings can also be defined in a way enclosed in brackets [[]]. We define N equal brackets between two positive square brackets (i.e. [[]) as positive brackets at level n. That is to say, level 0 positive bracket writing [, level 1 positive bracket writing [=[, and so on]. Inverse brackets are similarly defined; for example, level 4 inverse brackets are written]====. A long string can start with positive brackets at any level and end with the first count parentheses encountered. The whole lexical analysis process will not be subject to branch restrictions, will not handle any escapes, and will ignore any different levels of brackets. Strings described in this way can contain anything, except anti-brackets at this level. Example: [[abc nbc], the ” n” in it will not be escaped.

In addition, Lua’s string is an immutable value. It can’t modify a character of the string directly as in C language but create a new string according to the modification requirements. Lua also cannot access a character in a string by subscribing. For more information on string manipulation, see the String Library section.

In Lua implementations, Lua strings generally undergo an internalization process, that is, two identical Lua strings will only store one in the Lua virtual machine. Each Lua string is inserted into a global hash table inside the Lua virtual machine when it is created. That means:

  1. Creating the same Lua string does not introduce a new dynamic memory allocation operation, so it is relatively cheap (but there is still overhead for global hash table queries).
  2. Lua strings with the same content do not occupy multiple storage spaces.
  3. Comparing equality between created Lua strings is an overhead of O(1) time, not the usual O(n).


The Table type implements an abstract “associative array”. An associative array is an array with a special indexing method. The index is usually a string or number type, but it can also be any type of value other than nil.

local corp = {
    web = "",   --index is string,key = "web",
                              --value = ""
    telephone = "12345678",   --index is string
    staff = {"Jack", "Scott", "Gary"}, --index is string ,value is table
    100876,              -- [1] = 100876,index is number
                         -- key = 1, value = 100876
    100191,              --[2] = 100191,index is number
    [10] = 360,          --directly indexing numbers
    ["city"] = "Beijing" --index is string

print(corp.web)               -->
print(corp["telephone"])      -->output:12345678
print(corp[2])                -->output:100191
print(corp["city"])           -->output:"Beijing"
print(corp.staff[1])          -->output:Jack
print(corp[10])               -->output:360

In internal implementations, tables are usually implemented as a hash table, an array, or a mixture of the two. What form of implementation depends dynamically on the key distribution characteristics of specific tables.


In Lua, functions are also a data type. Functions can be stored in variables, passed to other functions through parameters, and can be used as return values of other functions.

local function foo()
    print("in the function")
    local x = 10
    local y = 20
    return x + y

local a = foo    --assign a function to a variable


in the function

The definition of a named function is essentially the assignment of variables by an anonymous function. To illustrate this point, consider

function foo()

Equivalent to

foo = function ()


local function foo()

Equivalent to

local foo = function ()