日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Lua中ipairs和pairs的区别

發布時間:2023/12/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Lua中ipairs和pairs的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Lua中ipairs和pairs的區別

  • 泛型for
  • ipairs的實現
  • pairs的實現
  • 兩者區別

泛型for

首先是泛型for的語法

for var-list in exp-list do body end

當執行for循環時候,泛型for會接收exp-list返回的三個值分別用作迭代函數、不可變狀態和控制變量的初始值。上述步驟完成后泛型for使用不可變狀態和控制變量為參數來調用迭代函數,泛型for將迭代函數的返回值賦給變量列表中聲明的變量,如果第一個返回值(賦給控制變量的值)為 nil ,那么循環終止;否則,泛型for執行它的循環體并再次調用迭代函數,再不斷地重復這個過程。
偽代碼是這樣的:

local _f, _s, _var = exp-list while true do local var_1, ... , var_n = _f(_s, _var)_var = var_1 if _var == nil then break end block end

而ipairs和pairs是lua提供的兩個迭代函數生成器也就是前面的exp-list

ipairs的實現

/* ** Traversal function for 'ipairs' */ static int ipairsaux (lua_State *L) {lua_Integer i = luaL_checkinteger(L, 2);// i = i + 1i = luaL_intop(+, i, 1);lua_pushinteger(L, i);// table[i] == nil and return 1 or return 2return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2; }/* ** 'ipairs' function. Returns 'ipairsaux', given "table", 0. ** (The given "table" may not be a table.) */ static int luaB_ipairs (lua_State *L) {luaL_checkany(L, 1);lua_pushcfunction(L, ipairsaux); /* iteration function */lua_pushvalue(L, 1); /* state */lua_pushinteger(L, 0); /* initial value */return 3; }

當我們使用ipairs的時候會調用luaB_ipairs,可以看到ipairs執行之后會返回三個參數,第一個參數是個遍歷函數ipairsaux,第二個是ipairs函數調用時候傳入的table,第三個參數是0。ipairs的遍歷函數是通過 i 作為table的key,不斷自增 i 從而達到遍歷的效果的。

可以理解為如下代碼:

local iter = function(t, i)i = i + 1local v = t[i]if v thenreturn i, vend endfunction ipairs(t)return iter, t, 0 end

pairs的實現

static int luaB_next (lua_State *L) {luaL_checktype(L, 1, LUA_TTABLE);lua_settop(L, 2); /* create a 2nd argument if there isn't one */if (lua_next(L, 1))return 2;else {lua_pushnil(L);return 1;} }static int pairscont (lua_State *L, int status, lua_KContext k) {(void)L; (void)status; (void)k; /* unused */return 3; }static int luaB_pairs (lua_State *L) {luaL_checkany(L, 1);if (luaL_getmetafield(L, 1, "__pairs") == LUA_TNIL) { /* no metamethod? */lua_pushcfunction(L, luaB_next); /* will return generator, */lua_pushvalue(L, 1); /* state, */lua_pushnil(L); /* and initial value */}else {lua_pushvalue(L, 1); /* argument 'self' to metamethod */lua_callk(L, 1, 3, 0, pairscont); /* get 3 values from metamethod */}return 3; }

當我們使用pairs的時候會調用luaB_pairs,在沒有__pairs元方法的時候,可以看到pairs執行之后返回三個參數,第一個參數是個遍歷函數luaB_next,第二個是pairs函數調用時候傳入的table,第三個參數是nil。這里的luaB_pairs使用的就是遍歷函數lua_next就是我們常用的next函數,也就是說pairs是通過不斷調用next函數達到遍歷的效果的。

可以理解為如下代碼:

function pairs(t)return next, t, nil end

兩者區別

由他們的實現可以看出兩者的區別
ipairs是沒法保證完整遍歷的,優勢是可以有序遍歷。
pairs是由于next的機制可以保證完整的遍歷,但是卻沒辦法保證順序。

-- 遇table1[3]==nil時終止 ipairs可遍歷到:a, b pairs可遍歷到:a, b, d local table1 = { "a", "b", nil, "d" } -- ipairs可遍歷到:a, b, d pairs可遍歷到:a, b, d local table2 = { "a", "b", c = 1, "d" }

總結

以上是生活随笔為你收集整理的Lua中ipairs和pairs的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。