iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0
Software Development

30天 Lua重拾筆記系列 第 17

【30天Lua重拾筆記17】基礎2: pcall, xpcall, load (eval, exec, apply)

同步發表於個人網站

eval / load

作為一個直譯的環境,幾乎一定會有一個與eval等價的能力,不過在Lua叫做load,與其他程式相同,這個功能是強大而應該小心使用的。下方程式會新建一個全局變數g1,使這個宣告過程原本是一段字串。

load([[
  g1 = 1 -- create a global variable g1
  ]])()

print(g1) -- => Output: 1

要注意的是,load不回直接執行,其實其返回一個包裝函式:

f = load[[g2 = 2]]
print(type(f)) -- => function

print(g2) -- => Output: nil
f()
print(g2) -- => Output: 2

ECMAScript

類似的JS也有。

不過相較於JS,Lua其實有更安全的作法(以後會提到)。

eval('var g1 = 1')
console.log(g1) // => Output: 1

Python

Python有兩個函式做類似事情--evalexec。不過eval雖有返回值,但無法執行語句,只能執行表達式。所以本例中只能使用execexec永遠回傳None,比起eval更加強大。

exec('''
global g1
g1 = 1
''')

print(g1)

※ Note: Python實際也有相對安全作法,以後一塊討論。

apply / pcall, xpcall

比起函數型語言裡的applycall,Lua的pcallxpcall另有用途,但未來在說。他們還是有點像的,可以觸發一個函式的執行。

pcall(print, "Hello, World") -- Output: Hello, World
xpcall(print, function(msg)end, "Hello, Lua") -- Output: Hello, Lua

這邊先BJ4,先看看其他語言類似的例子。

ECMAScript

console.log.call(console, "Hello, Wold")
// note: console.log實際上已經bind了,所以第一個參數會被忽略

Common Lisp

作為一個函數型語言,用法很正常。

(funcall #'print "Hello, World")
(apply #'print '("Hello, World"))

上一篇
【30天Lua重拾筆記16】基礎2: 多值返回&具名參數
下一篇
【30天Lua重拾筆記18】基礎2: 應該知道的(總集+補充)
系列文
30天 Lua重拾筆記36

尚未有邦友留言

立即登入留言