初阶话题

时间:2024-04-14 11:23:39

八种基本类型

基本类型 描述 备注
数值(number) 内部以double表示
字符串(string) 总是以零结尾,但可以包含任意字符(包括零),因此并不等价于C字符串, 而是其超集
布尔(boolean) 只有“true”或者“false”两个值。
函数(function) Lua的关键概念之一。不简单等同于C的函数或函数指针。
表(table) 异构的Hash表。Lua的关键概念之一。
userdata 用户(非脚本用户)定义的C数据结构。脚本用户只能使用它,不能定义。
线程(thread) Lua协作线程(coroutine),与一般操作系统的抢占式线程不一样。
nil 代表什么也没有,可以与C的NULL作类比,但它不是空指针。

函数

实例代码

function foo(a, b, c, ...)
    local sum = a + b
    return sum, c --函数可以返回多个值
end
r1, r2 = foo(1, "123", "hello") --平行赋值 print(r1,r2);

输出结果

124hello

函数基本使用方法

  • 函数定义
    用关键字function定义函数,以关键字end结束

  • 局部变量
    用关键字local定义。如果没有用local定义,即使在函数内部定义的变量也是全局变量

  • 函数可以返回多个值
    return a, b, c, …

  • 平行赋值
    a,b = c, d

  • 全局变量
    前面的代码定义了三个全局变量:foo、r1和r2

实例代码

local a = {}
    local b = {x = 1,["hello,"] = "world!"}
    a["astring"] = "ni,hao!"
    a[1] = 100
    a["a table"] = b

    for k,v in  pairs(a) do
        print(k,"=>",v);
    end

输出结果

1=>100

astring=>ni,hao!

atable=>table: 0xfd59570

表使用方法

  • 定义表(Table)的方式
    a={}, b = {…}

  • 访问表的成员
    通过 . 或者 [] 运算符来访问表的成员。
    注意:表达式a.b等价于a[b],但不等价于a[b]

  • 表项的键和值
    任何类型的变量,除了nil,都可以做为表项的键。从简单的数值、字符串到复杂的函数、表等等都可以;同样,任何类型的变量,除了nil,都可以作为表项的值。给一个表项的值赋nil意味着从表中删除这一项,比如令a.b= nil,则把表a中键为b的项删除。如果访问一个不存在的表项,其值也是nil,比如有c = a.b,但表a中没有键为b的项,则c等于nil

一种简单的对象实现方式

实现代码

function create(name,id)
        local obj = {name = name,id = id}

        function obj:SetName(name)
            self.name = name 
        end

        function obj:GetName()
            return self.name
        end

        function obj:SetId(id)
            self.id = id
        end

        function obj:GetId()
            return self.id
        end
        return obj
    end

    local myCreate = create("sam",001)

    for k,v in pairs(myCreate) do
        print(k,"=>",v)
    end

    print("myCreate's name:",myCreate:GetName(),"myCreate's id:",myCreate.GetId(myCreate))

    myCreate:SetId(100)
    myCreate:SetName("Hello Kity")

    print("myCreate's name:",myCreate:GetName(),"myCreate's id:",myCreate:GetId())

输出结果

SetName=>function: 0x85efc50

GetId=>function: 0x85efc10

id=>1

SetId=>function: 0x85efd00

GetName=>function: 0x85efce0

name=>sam

myCreate’s name:sammyCreate’s id:1

myCreate’s name:Hello KitymyCreate’s id:100

对象实现描述

  • 对象工厂模式
    如前面代码的create函数

  • 用表来表示对象
    把对象的数据和方法都放在一张表内,虽然没有隐藏私有成员,但对于简单脚本来说完全可以接受。

  • 成员方法的定义
    function obj:method(a1, a2, …) … end 等价于function obj.method(self, a1, a2, …) … end 等价于obj.method = function (self, a1, a2, …) … end

  • 成员方法的调用
    obj:method(a1, a2, …) 等价于obj.method(obj, a1, a2, …)

简单继承

实现代码

 local function CreateRobot(name, id)
    local obj = {name = name, id = id}
    function obj:SetName(name)
        self.name = name
    end
    function obj:GetName()
        return self.name
    end
    function obj:SetId(id)
        self.id = id
    end
    function obj:GetId()
        return self.id
    end
    return obj
end
local function createFootballRobot(name, id, position)
    local obj = CreateRobot(name, id)
    obj.position = "right back"
    function obj:SetPosition(p)
        self.position = p
    end
    function obj:GetPosition()
        return self.position
    end
    return obj
end
local mycreateFootballRobot = createFootballRobot("Tom", 1000, "广州")
print(
    "mycreateFootballRobot's name:",
    mycreateFootballRobot:GetName(),
    "myCreate's id:",
    mycreateFootballRobot:GetId(),
    mycreateFootballRobot:GetPosition()
)
mycreateFootballRobot:SetName("麦迪")
mycreateFootballRobot:SetId(2000)
mycreateFootballRobot:SetPosition("北京")
print(
    "mycreateFootballRobot's name:",
    mycreateFootballRobot:GetName(),
    "myCreate's id:",
    mycreateFootballRobot:GetId(),
    mycreateFootballRobot:GetPosition()
)

输出结果

mycreateFootballRobot’s name:TommyCreate’s id:1000right back
mycreateFootballRobot’s name:麦迪myCreate’s id:2000北京

简单继承优缺点

  • 优点:
    简单、直观
  • 缺点:
    传统、不够动态

参考文献《C/C++程序员的Lua快速入门》