初探 lua 的唯一数据结构 table

2019-06-22  本文已影响0人  OOM_Killer

在lua的世界中是只有一种数据结构的,那就是table。
而 table 做了在其他语言中,高级特性该做的所有事情。

table 中的数组和hash

这个是比较诡异的一种操作。没错,hash和数组在一起。举个例子

local color = {first="red","blue",third="green","yellow"}
print(color["first"])   -- red
print(color[1])         -- blue
print(color[2])         -- yellow
print(color)            -- table: 0x41d99d48

当取下标时,只取出数组部分,当取键时,就是去取hash部分。
而table本身如果打印的话,他只是一个地址。

lua 的数组下标是从1开始的,这点需要注意了。

而遍历他们,lua又提供了两个方法,就是ipair和pair。

local color = {first="red","blue",third="green","yellow"}
for k,v in ipairs(color) do 
    print(k,v)
end
-- 1       blue
-- 2       yellow

for k,v in pairs(color) do 
    print(k,v)
end

-- 1       blue
-- 2       yellow
-- third   green
-- first   red

table 的库函数

local color = {first="red","blue",third="green","yellow","black"}
print(table.getn(color))  -- 3
print(#color)             -- 3
local color = {first="red","blue",third="green","yellow","black"}
table.remove(color,1)
for k,v in pairs(color) do 
    print(k,v)
end
-- 1       yellow
-- 2       black
-- third   green
-- first   red

如果是删除 hash 部分的话就是 将指定的 元素设置成nil。同时,这样也是对内存的释放。

local color = {first="red","blue",third="green","yellow","black"}
table.remove(color,1)
color.first = nil
for k,v in pairs(color) do 
    print(k,v)
end
-- 1       yellow
-- 2       black
-- third   green
local color = {first="red","blue",third="green","yellow","black"}
print(table.concat(color,","))
-- blue,yellow,black
print(table.concat(color,",",2))
-- yellow,black

中间的“,”是指将 数组中的元素以什么为分割符分割。如果最后还跟着数字,则指的是取该数字以后的元素。

local color = {first="red","blue",third="green","yellow","black"}
table.insert(color,1,"orange")
for k,v in pairs(color) do
    print(k,v)
end
local new_tab = require "table.new" -- 需要luajit-2.1.0-beta3

local t = new_tab(10,5)
for i = 1,10 do
    t[i] = i
end
local clear_tab = require "table.clear" -- 需要luajit-2.1.0-beta3

local color = {first = "red", "blue", third = "green", "yellow"}
clear_tab(color)
for k,v in pairs(color) do 
    print(k,v)
end

元表

元表(metatable)。元表是Lua中独有的概念,在实际的项目中,就是靠元表来对lua作面向对象编程的,在几乎所有的lua-resty-* 库中,都有他的身影。
最重要的函数辅助元表的处理。

类似python中的魔术方法,lua在这方面也有类似的做法。

local v = { bar = 1 }
t = setmetatable({}, { __index = v})
print(t.bar)
-- 1
local t = {}
myt = setmetatable({k1 = "v1"}, {__newindex = t})

print(myt.k1)
-- v1

myt.k2 = "v2"
print(myt.k2,t.k2)
-- nil v2

myt.k1 = "new_v1"
print(myt.k1,t.k1)
-- new_v1 nil
local t = { 
    major = 5,
    minor = 3,
    patch = 102
}
myt = setmetatable(t, {
    __index = { name = "lua" },
    __tostring = function (t)
        return string.format( "%s version is %d.%d.%d",t.name,t.major,t.minor,t.patch )
    end
})

print(tostring(myt))
- lua version is 5.3.102
local version = { 
    name = "lua",
    major = 5,
    minor = 3,
    patch = 102
}

local function print_version(t)
    print(string.format( "%s version is %d.%d.%d",t.name,t.major,t.minor,t.patch ))
end

version  = setmetatable( version, { __call = print_version })

version()

面向对象

面向对象是众多编程语言的所支持的。
其主要特点有:

  1. 封装:能把一个实体的信息,功能装入一个变量或对象里。
  2. 继承:在不改动原有方法的基础上,对其进行扩充。
  3. 多态:在同一操作作用于不同的对象时。可以有不同的解释。
  4. 抽象: 简化复杂现实问题的解决。
-- Meta class
Rectangle = {
    area    = 0,
    length  = 0,
    breadth = 0,
}

function Rectangle:new ( o,length,breadth )
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    self.length  = length or 0
    self.breadth = breadth or 0
    self.area    = length * breadth
    return o
end

function Rectangle:printArea()
    print("矩形面积为 ",self.area)
end

-- 创建对象
r = Rectangle:new(nil,10,20)

-- 访问属性
print("矩形的长为",r.length)
-- 矩形的长为      10

-- 访问成员函数
r:printArea()    -- 或者写成 r.printArea(r)  用 :号表示是一个语法糖
-- 矩形面积为      200
上一篇下一篇

猜你喜欢

热点阅读