前言#
看了前幾篇自己總結的文章,我發現了一個問題,那就是從標題上不能直接的看出文章所講的內容,所以從這一章開始我要改變標題的風格,直接把要總結的api列在標題上,這樣看起來更醒目,也更容易查找。
言歸正傳,前兩章我們講了對通用table的操作,然而我們知道在table中有個特例是我們使用頻率相當高的,那就是數組,數組本來就是“一串”的,有沒有更簡便的存取方法呢,答案當然是肯定的,lua為我們提供了以下兩個api可以直接對數組進行操作。
內容#
lua_rawgeti##
- 原型:void lua_rawgeti (lua_State *L, int index, int n);
- 解釋:把 t[n] 的值壓棧, 這里的 t 是指給定索引 index 處的一個值。 這是一個直接訪問,它不會觸發元方法。
lua_rawseti##
- 原型:void lua_rawseti (lua_State *L, int index, int n);
- 解釋: 等價于 t[n] = v, 這里的 t 是指給定索引 index 處的一個值, 而 v 是棧頂的值。函數將把這個值彈出棧。 賦值操作是直接的,不會觸發元方法。
Usage##
- 首先我們來新建一個文件,文件命名為rawgetitest.lua編寫如下代碼:
-- 定義一個全局table
LanguagesTable =
{
"lua",
"c",
"c++",
"java",
"python",
}
-- 定義一個打印函數
function func_printarray()
print("\n");
for index,value in pairs(LanguagesTable) do
print("["..index.."] = ".. value);
end
end
- 然后我們編寫c++代碼如下:
lua_State *L = lua_open();
luaL_openlibs(L);
luaL_dofile(L,"rawgetitest.lua"); // 加載執行lua文件
lua_getglobal(L,"LanguagesTable"); // 將全局表壓入棧
lua_rawgeti(L, -1, 2); // 取LanguagesTable[2]的值-->lua_rawgeti用法
if(lua_isnil(L, -1))
{
printf("c++ --> [2] = nil\n");
}
else
{
printf("c++ --> [2] = %s\n", lua_tostring(L, -1));
}
lua_pop(L,1); // 彈出棧頂變量
lua_getglobal(L, "func_printarray");// 改變之前先調用打印函數,查看原數組
lua_pcall(L, 0, 0, 0);
lua_pushstring(L, "php"); // 將要賦值的結果壓入棧
lua_rawseti(L, -2, 4); // 賦值操作 -->lua_rawseti用法
lua_pushstring(L, "swift"); // 將要賦值的結果壓入棧
lua_rawseti(L, -2, 8); // 賦值操作 -->lua_rawseti用法
lua_getglobal(L, "func_printarray");// 改變之后再調用打印函數,查看改變后的結果
lua_pcall(L, 0, 0, 0);
lua_close(L); //關閉lua環境
- 結果
rawgeti.png
總結#
- 從api的名字我們可以看到這兩個方法是帶有“raw”前綴的,可以推斷出這兩個方法不會調用table的元方法。
- 既然是對數組進行操作,那么肯定少不了對下標的使用,兩個api函數的第3個參數都表示下標,注意table數組的下標是從1開始的。
- 從結果可以看到我們可以直接按下標進行修改,并且下標可以是不連續的。
- 注意數組不連續時遍歷table的方法。