作者hmml (hmml)
看板mud_sanc
标题[心得] MUSHclient - loadstring 的用法
时间Sun Sep 29 10:53:37 2013
loadstring 在Lua的说明,是将一段被定义为字串的内容载为可
被执行的项目。不过使用上要多尝试几次才能知道特性。用范例
来看比较容易明白:
范例来源:
http://www.cnblogs.com/chuwp/archive/2010/01/24/1655065.html
例一:
i = 1 --i 值为1
b = "i = i + 1"
loadstring ( b )() --载入字串i = i + 1
print (i) --印出i,得2。
相信有用MUSHclient的都知道,以下两者的不同:
"i = i + 1"
i = i + 1
有加""的是字串,里面的i,就单纯只是一个字母,不是变数,所以b
是不能作为数学运算的内容,当用 print(b) 希望能求值时,也只会
得到 i = i + 1这个字串,而非期望的2。而 loadstring 就是将字串
载入成为可运算的内容的函数。本例可以知道 loadstring 可以使用
loadstring (字串)() 来直接求值。
例二:
i = 1
b = "i = i + 1"
f = loadstring (b)
f()
print (i)
本例跟例一相同,只是表现loadstring使用上的另一种格式。它将
loadstring (b) 放入f中,直接在f後方加上()执行,不明含意的
话,自行把f()的f改回loadstring (b),应该会明白这跟例一完全
相同,只是多绕个弯罢了。loadstring加载入的字串,类型会被改
变,将loadstring(字串)()的第二个()拿掉并执行印出,或将本例
的f(),直接print(f),都会得出
function: 06FD9560
类似这样的内容,告知类型已经变成函数。
例三:
local
strFun = " func "
local
nInt = 5
local
sName = " \' attacker\'"
--不能为"attacker",否则loadstring会认为全域变数attacker
function
func(
nParam1,
sParam2)
print (
nParam1)
print (
sParam2)
end
local foo =
loadstring (strFun .." (
"..nInt.." ,
"..sName.." )
")
--foo 期望内容为 func ( 5 , " attacker") 。
--但未用loadstring挂载,内容只是:strFun(nInt,sName)
--透过loadstring,foo的内容变成一个函数类型。
foo()
这个例子就比较复杂,它将各变数的内容串接成一个函数字串载入执行。
但要注意的只有变数里""的使用。
例四:
local a = "GetInfo(b)"
local b = 1
a = string.gsub(a,'b',b)
print ("印出a:",a)
print ("印出GetInfo(1)结果:",GetInfo(1))
print ("印出GetInfo(1)本次ID:",loadstring(a))
print ("格式一:"..loadstring(a)())
print ("加上return:"..loadstring('return '..a)())
用 MUSHclient 里的函数来测试一下,GetInfo(1)用来检视目前所连伺服器
位址。正常情况下,加载的写法应为:
local a = "GetInfo"
local b = 1
print(loadstring("return "..a.."("..b..")")())
不过加载每次都要写这麽长实在很麻烦。而且看了会很花。所以期望上希望
能:
local a = "GetInfo(b)"
local b = 1
print (loadstring("return "..b)())
甚至:
local a = "return GetInfo(b)"
local b = 1
print (loadstring(b)())
否则当要印出一段多种函数组合的结果,就要准备很多字段,字段数量不一
,将很难标准化如:
string.format("%%-10.10s", GetPluginTriggerInfo ('','v
',26))..GetPluginTriggerInfo ("", 'v', 1)
string.format("%%-8s",GetPluginTimerInfo ("", 'v',
1)..":"..GetPluginTimerInfo ("", 'v', 2)..":"..GetPluginTimerInfo ("", 'v',
3))..GetPluginTimerInfo ("", 'v', 4)
以v为断句,第一段必须准备三个变数去放置,第二段要准备五个变数去放置内容,
这样不好管理。串接也变得复杂。要用特定指定变换来呼叫指定内容去执行,也因
变数数量不同变得麻烦。
但当你使用:
local a = "return GetInfo(b)"
loadstring 在载入它时,它会错判 b 而不将b的内容置入。造成错误无法执行。
欲用:
local a = "return GetInfo("..b..")"
lua 会跟你要 b 的内容,你没给同样造成错误。而格式也复杂了。
有个折衷的做法:
local a = "GetInfo(b)"
local b = 1
a = string.gsub(a,'b',b)
当你要用loadstring加载a之前,先用string.gsub将字串b,置换成变数b的内容。
这将便能正确执行。
另外,匹配後取得的内容,使用%1,%2...置入的内容,loadstring可以直接读到,
即:
local a = "GetInfo(%1)"
print (loadstring("return "..b)())
可以得到结果...
return 的使用时机,当你未加 return ,却未回传结果,也未报错,就该用用看
,因为它不知道要回传,需要你加上这个来表示。
应用上,如:
DoAfterSpecial (0.1,内容,12)
因为内容是变数或表,之前找不出执行的方法,只好使用DoAfterSpecial。明白
loadstring後,可以改为:
loadstring(内容)()
来执行!
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.132.196.45
※ 编辑: hmml 来自: 220.132.196.45 (09/29 10:56)