新文章 - Lua中的ipair 和 pair的区别 / table

2024-09-04 10:32
文章标签 文章 区别 table lua pair ipair

本文主要是介绍新文章 - Lua中的ipair 和 pair的区别 / table,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 参考博客:  https://blog.csdn.net/W_han__/article/details/51376615 (https://blog.csdn.net/heyuchang666/article/details/51003492)

 参考博客:  https://www.jianshu.com/p/4db84cf0d61a(初探 lua 的唯一数据结构 table)

----------------------------------------------------------------------------------------------------

原来,pairs会遍历table的所有键值对。table是键值对的数据结构。

而ipairs就是固定地从key值1开始,下次key累加1进行遍历,如果key对应的value不存在,就停止遍历。顺便说下,记忆也很简单,带i的就是根据integer key值从1开始遍历的。

请看个例子:
tb = {"oh", [3] = "god", "my", [5] = "hello", [6] = "world"}

for k,v in ipairs(tb) do
     print(k, v)
end
输出结果就是:
1       oh
2       my
3       god
因为tb不存在tb[4],所以遍历到此为止了。

for k,v in pairs(tb) do
     print(k, v)
end
输出结果:
1       oh
2       my
3       god
6       world
5       hello
我们都能猜到,将输出所有的内容。然而你发现输出的顺序跟你tb中的顺序不同。
如果我们要按顺序输出怎么办?办法之一是:
for i = 1, #tb do
     if tb[i] then
          print(tb[i])
     else
end
当然,仅仅是个数组的话,ipairs也没问题。
———————————————————————————————————————————————————————— 
 

在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       yellowfor k,v in pairs(color) do print(k,v)
end-- 1       blue
-- 2       yellow
-- third   green
-- first   red

table 的库函数

  • table.getn 获得table的长度
    对于一个序列,其元素个数是getn或者一元操作符 # 。其取的长度都是数组的。
    且其操作是O(N)的,所以尽量在长度很长的情况下避免使用。

 

local color = {first="red","blue",third="green","yellow","black"}
print(table.getn(color))  -- 3
print(#color)             -- 3
  • table.remove 删除指定元素
    删除元素,只是说删除 数组部分,也就是使用下标去删除的。

 

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
  • table.concat 元素拼接
    按照此方式,把table中的元素拼接起来,同样的,还是针对的是一个table中的数组部分。

 

local color = {first="red","blue",third="green","yellow","black"}
print(table.concat(color,","))
-- blue,yellow,black
print(table.concat(color,",",2))
-- yellow,black

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

  • table.insert 插入一个元素
    同样,这是对数组操作的了。但是insert的插入性能不乐观,如果不是指定下标去插入元素的话,那么每次需要调用Luajit的 lj_table_len 来获取数组的长度。以便插入队尾。
    所以在热代码处减少对insert的使用

 

local color = {first="red","blue",third="green","yellow","black"}
table.insert(color,1,"orange")
for k,v in pairs(color) doprint(k,v)
end
  • table.new 新建一个table
    这是luajit的table扩展函数。用来新建table。这个函数会预先分配好指定数组和hash的空间大小。而不是在插入元素时自增长
    table.new(narray,nhash) 正是这个含义。
    因为自增长是一个代价非常高的操作。,会涉及到空间分配,resize和rehash等。
    因为是扩展出来的,所以使用的时候需要require一下。

 

local new_tab = require "table.new" -- 需要luajit-2.1.0-beta3local t = new_tab(10,5)
for i = 1,10 dot[i] = i
end
  • table.clear 清空table
    这个同样是函数 table.clear() 里面的函数,用来清空某个table里面的所有数据。但并不会释放数组和hash所占用的内存。
    所以,在循环利用lua table时比较有效。可以避免反复的创建和销毁。

 

local clear_tab = require "table.clear" -- 需要luajit-2.1.0-beta3local 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-* 库中,都有他的身影。
最重要的函数辅助元表的处理。

  • setmetatable(table,metatable): 对指定表设置元表,如果元表中存在 _metatable 键值,setmetatable会失败。
  • getmetatable(table),用于获取table的元素。

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

  • __index 元方法
    __index 是元表中最常用的键值。当通过键访问表时,如果这个键没有值,则会寻找该元表的__index值。

 

local v = { bar = 1 }
t = setmetatable({}, { __index = v})
print(t.bar)
-- 1
  • __newindex 元方法
    该方法对表进行更新,_index 用来对表访问,当给表一个不存在的索引的时候,解释器会查找__newindex 元方法。

 

local t = {}
myt = setmetatable({k1 = "v1"}, {__newindex = t})print(myt.k1)
-- v1myt.k2 = "v2"
print(myt.k2,t.k2)
-- nil v2myt.k1 = "new_v1"
print(myt.k1,t.k1)
-- new_v1 nil
  • __tostring 元方法
    __tostring 元方法是用来改变一个表的输出行为。
    比如

 

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
  • __call 元方法
    可以让表像方法一样被调用。

 

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 ))
endversion  = 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 = selfself.length  = length or 0self.breadth = breadth or 0self.area    = length * breadthreturn o
endfunction Rectangle:printArea()print("矩形面积为 ",self.area)
end-- 创建对象
r = Rectangle:new(nil,10,20)-- 访问属性
print("矩形的长为",r.length)
-- 矩形的长为      10-- 访问成员函数
r:printArea()    -- 或者写成 r.printArea(r)  用 :号表示是一个语法糖
-- 矩形面积为      200



 

这篇关于新文章 - Lua中的ipair 和 pair的区别 / table的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1135774

相关文章

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

javascript中break与continue的区别

在javascript中,break是结束整个循环,break下面的语句不再执行了 for(let i=1;i<=5;i++){if(i===3){break}document.write(i) } 上面的代码中,当i=1时,执行打印输出语句,当i=2时,执行打印输出语句,当i=3时,遇到break了,整个循环就结束了。 执行结果是12 continue语句是停止当前循环,返回从头开始。

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令

maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令 在日常的工作中由于各种原因,会出现这样一种情况,某些项目并没有打包至mvnrepository。如果采用原始直接打包放到lib目录的方式进行处理,便对项目的管理带来一些不必要的麻烦。例如版本升级后需要重新打包并,替换原有jar包等等一些额外的工作量和麻烦。为了避免这些不必要的麻烦,通常我们

ActiveMQ—Queue与Topic区别

Queue与Topic区别 转自:http://blog.csdn.net/qq_21033663/article/details/52458305 队列(Queue)和主题(Topic)是JMS支持的两种消息传递模型:         1、点对点(point-to-point,简称PTP)Queue消息传递模型:         通过该消息传递模型,一个应用程序(即消息生产者)可以

深入探讨:ECMAScript与JavaScript的区别

在前端开发的世界中,JavaScript无疑是最受欢迎的编程语言之一。然而,很多开发者在使用JavaScript时,可能并不清楚ECMAScript与JavaScript之间的关系和区别。本文将深入探讨这两者的不同之处,并通过案例帮助大家更好地理解。 一、什么是ECMAScript? ECMAScript(简称ES)是一种脚本语言的标准,由ECMA国际组织制定。它定义了语言的语法、类型、语句、

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

由Lua 粘合的Nginx生态环境

转自:http://blog-zq-org.qiniucdn.com/pyblosxom/oss/openresty-intro-2012-03-06-01-13.html -- agentzh tech-club.org 演讲听录 免责聲明 Lua 粘合的 Nginx 生态环境 2.1. openresty 2.2. 配置小语言 2.3. ngx_drizzle 2.4.

java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频)

这是什么系统? 资源获取方式在最下方 java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频) 停车管理信息系统是为了提升停车场的运营效率和管理水平而设计的综合性平台。系统涵盖用户信息管理、车位管理、收费管理、违规车辆处理等多个功能模块,旨在实现对停车场资源的高效配置和实时监控。此外,系统还提供了资讯管理和统计查询功能,帮助管理者及时发布信息并进行数据分析,为停车场的科学