计算机语言中的元表及元方法是什么呢?

计算机语言中的元表及元方法是什么呢?,第1张

元表及元方法,Lua 中的每个值都可以有一个 元表。 

1这个 元表 就是一个普通的 Lua 表, 它用于定义原始值在特定 *** 作下的行为。 如果你想改变一个值在特定 *** 作下的行为,你可以在它的元表中设置对应域。 例如,当你对非数字制作加 *** 作时, Lua 会检查该值的元表中的 "__add" 域下的函数。 如果能找到,Lua 则调用这个函数来完成加这个 *** 作。

2元表中的键对应着不同的 事件 名; 键关联的那些值被称为 元方法。 在上面那个例子中引用的事件为 "add" , 完成加 *** 作的那个函数就是元方法。

你可以用 getmetatable 函数 来获取任何值的元表。

3使用 setmetatable 来替换一张表的元表。在 Lua 中,你不可以改变表以外其它类型的值的元表 (除非你使用调试库(参见§610)); 若想改变这些非表类型的值的元表,请使用 C API。

4表和完全用户数据有独立的元表 (当然,多个表和用户数据可以共享同一个元表)。 其它类型的值按类型共享元表; 也就是说所有的数字都共享同一个元表, 所有的字符串共享另一个元表等等。 默认情况下,值是没有元表的, 但字符串库在初始化的时候为字符串类型设置了元表 (参见 §64)。

5元表决定了一个对象在数学运算、位运算、比较、连接、 取长度、调用、索引时的行为。 元表还可以定义一个函数,当表对象或用户数据对象在垃圾回收 (参见§25)时调用它。

接下来会给出一张元表可以控制的事件的完整列表。 每个 *** 作都用对应的事件名来区分。 每个事件的键名用加有 '__' 前缀的字符串来表示; 例如 "add" *** 作的键名为字符串 "__add"。 注意、Lua 从元表中直接获取元方法; 访问元表中的元方法永远不会触发另一次元方法。 下面的代码模拟了 Lua 从一个对象 obj 中获取一个元方法的过程:

rawget(getmetatable(obj) or {}, "__" event_name)

6对于一元 *** 作符(取负、求长度、位反), 元方法调用的时候,第二个参数是个哑元,其值等于第一个参数。 这样处理仅仅是为了简化 Lua 的内部实现 (这样处理可以让所有的 *** 作都和二元 *** 作一致), 这个行为有可能在将来的版本中移除。 (使用这个额外参数的行为都是不确定的。)

"add": + *** 作。 如果任何不是数字的值(包括不能转换为数字的字符串)做加法, Lua 就会尝试调用元方法。 首先、Lua 检查第一个 *** 作数(即使它是合法的), 如果这个 *** 作数没有为 "__add" 事件定义元方法, Lua 就会接着检查第二个 *** 作数。 一旦 Lua 找到了元方法, 它将把两个 *** 作数作为参数传入元方法, 元方法的结果(调整为单个值)作为这个 *** 作的结果。 如果找不到元方法,将抛出一个错误。

"sub": - *** 作。 行为和 "add" *** 作类似。

"mul": *** 作。 行为和 "add" *** 作类似。

"div": / *** 作。 行为和 "add" *** 作类似。

"mod": % *** 作。 行为和 "add" *** 作类似。

"pow": ^ (次方) *** 作。 行为和 "add" *** 作类似。

"unm": - (取负) *** 作。 行为和 "add" *** 作类似。

"idiv": // (向下取整除法) *** 作。 行为和 "add" *** 作类似

  如果没说错的话,这个宏有错误或这个宏不是完整的。

  首先解释下宏的意思

  /script if (UnitClass("target")=="Warrior") then SendChatMessage("", "WHISPER") else

  脚本 判断 目标是否为战士,如果是就悄悄话M他说“”否则

  if (UnitClass("target"))=="Roque" then SendChatMessage("", "WHISPER") else

  判断 目标是否为盗贼,如果是就悄悄话M他说“”否则

  if (UnitClass("target"))=="Priest" then SendChatMessage("", "WHISPER") else

  判断 目标是否为牧师,如果是就悄悄话M他说“”否则

  if (UnitClass("target"))=="Mage" then SendChatMessage("", "WHISPER") else

  判断 目标是否为法师,如果是就悄悄话M他说“”否则

  if (UnitClass("target"))=="Hunter" then SendChatMessage("", "WHISPER") else

  判断 目标是否为猎人,如果是就悄悄话M他说“”否则

  SendChatMessage("", "WHISPER") end end end end end

  如果都不满足以上条件直接对目标悄悄话M“”;

  /script SendChatMessage("", "WHISPER")

  脚本M话方式;

  结素。

  这个宏应该是判断目标什么职业然后做出相应的M话,M话内容应该在SendChatMessage("", "WHISPER")这个函数的""里。WHISPER是选择对话方式,不写默认为普通。

  补充:

  不好意思,前就几天由于忙,没时间来,现在仔细看了看。终于发现问题的所在。问题如下:

  首先了解下这个函数SendChatMessage()参数结构:

  SendChatMessage("message","system","language","channel");

  不知道为什么,惟独当system参数为whisper时需要加完整的参数。

  我把你的宏改了下。(一定要注意,为了保证宏的正确性,要直接复制,格式和位置千万不要改动)具体如下:

  /script if UnitClass("target")=="战士"then SendChatMessage('你要说的内容','whisper',thislanguage,UnitName('target'));else if UnitClass("target")=="盗贼"then SendChatMessage('你要说的内容','whisper',thislanguage,UnitName('target'));else if UnitClass("target")=="牧师"then SendChatMessage('你要说的内容','whisper',thislanguage,UnitName('target'));else if UnitClass("target")=="法师"then SendChatMessage('你要说的内容','whisper',thislanguage,UnitName('target'));else if UnitClass("target")=="猎人"then SendChatMessage('你要说的内容','whisper',thislanguage,UnitName('target'));else SendChatMessage('你要说的内容','whisper',thislanguage,UnitName('target'));end end end end end

  我是在记事本上敲的貌似贴进来位置变了,记得,用的时候千万不要为了美观换行(shilong_1229原创)

  国际惯例:2区 爱斯特纳巨魔猎人

lua在utf8下一个中文字长度为3,这样在中英文混排时截取字符串就比较麻烦,下面的函数是中文字长度为1下的处理

-- 获取utf8编码字符串长度,中文长度为1

function utfstrlen(str)

local len = #str;

local left = len;

local cnt = 0;

local arr={0,0xc0,0xe0,0xf0,0xf8,0xfc};

while left ~= 0 do

local tmp=stringbyte(str,-left);

local i=#arr;

while arr[i] do

if tmp>=arr[i] then left=left-i;break;end

i=i-1;

end

cnt=cnt+1;

end

return cnt;

end

--截取中英文混合字符串

--参数

-- string str 原始字符串

-- number start 起始位置,注意中文长度为1

-- number len 截取长度

--返回值

-- string 截取后的字符串

--备注

-- 1)中文UTF8默认占3个字节,可能对于一些占2个或4个字节的中文处理有问题

-- 2)回车\n等特殊控制字符也算一个长度

function subUTF8String(str, start, len)

local firstResult = ""

local strResult = ""

local maxLen = stringlen(str)

start = start - 1

--找到起始位置

local preSite = 1

if start > 0 then

for i = 1, maxLen do

local s_dropping = stringbyte(str, i)

if not s_dropping then

local s_str = stringsub(str, preSite, i - 1)

preSite = i + 1

break

end

if s_dropping < 128 or (i + 1 - preSite) == 3 then

local s_str = stringsub(str, preSite, i)

preSite = i + 1

firstResult = firstResults_str

local curLen = utfstrlen(firstResult)

if (curLen == start) then

break

end

end

end

end

--截取字符串

preSite = stringlen(firstResult) + 1

local startC = preSite

for i = startC, maxLen do

local s_dropping = stringbyte(str, i)

if not s_dropping then

local s_str = stringsub(str, preSite, i - 1)

preSite = i

strResult = strResults_str

return strResult

end

if s_dropping < 128 or (i + 1 - preSite) == 3 then

local s_str = stringsub(str, preSite, i)

preSite = i + 1

strResult = strResults_str

local curLen = utfstrlen(strResult)

if (curLen == len) then

return strResult

end

end

end

return strResult

end

例如:

print(subUTF8String("我爱死你们", 2, 3))

print(subUTF8String("abcde", 2, 3))

print(subUTF8String("我11爱死你们", 2, 3))

print(subUTF8String("我1", 2, 3))

print(subUTF8String("我日1爱死你们", 2, 3))

的结果是

[LUA-print] 爱死你

[LUA-print] bcd

[LUA-print] 11爱

[LUA-print] 1

[LUA-print] 日1爱

程序开发中模块的理解是什么。

程序模块即可由汇编程序、编译程序、装入程序或翻译程序作为一个整体来处理的一级独立的、可识别的程序指令。

模块是大型程序指令的一个组成部分。 在Windows中,术语“模块”一般是指任何能被装入内存中运行的可执行代码和数据的集合。更明确地讲,模块指的就是一个EXE文件(又称为应用程序模块),或一个动态链接库,或一个设备驱动程序,也可能是一个程序包含的能被另一个程序存取的数据资源。

模块一词也被用于特指自包含的一段程序。

简单来说,模块即可以说是功能的一部分,比如通信模块,也可以是一段程序,比如常量模块。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/12176209.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存