深入函式第一篇
- 函式是第一類值,具有特定的詞法域
第一類值
- 第一類值的意思是函式與 lua 中的其他型別如數字,字串具有相同的權力
- 函式可以存盤到全域變數或區域變數變數,還可以存盤到 table 中
- 可作為實參傳遞給其他函式,也可以作為其他函式的回傳值
詞法域
-
定義:一個函式可以嵌套在另一個函式中,內部函式可以訪問外部函式定義的區域變數
-
函式與其他所有的值一樣都是匿名的,沒有名稱
-
討論
print()函式時,相當于在討論值僅為print()的變數
a = {p = print}
a.p("Hello World") -- Hello World
c = print
c("eee") -- eee
print = math.sin
a.p(print(math.pi / 2)) -- 1
sin = a.p
sin(10, 20) -- 10 20
function foo(x)
return 2 * x
end
-- 等價于
foo = function (x) return 2 * x end
匿名函式
- 一個函式定義可以是一條賦值陳述句,這樣的函式運算式可以視為函式構造式,這種函式構造式的結果稱為匿名函式
- 一般會將函式賦予全域變數
function foo(x)
return 2 * x
end
-- 等價于
foo = function(x) return 2 * x end
高階函式
- 像
table.sort()這樣的函式接收另一個函式作為實參的函式就稱它為高階函式
-- table.sort 對 table 中的所有元素進行排序
network = {
{name = "atest", IP = "255.255.255.0",}
{name = "btest2"}, IP = "255.255.255.1"},
{name = "ctest3"}, IP = "255.255.255.3"},
{name = "dtest4"}, IP = "255.255.255.4"},
}
table.sort(network,
function (a, b)
return (a.name > b. name)
end
)
-- 導數 (f(x + d) - f(x)) / d 函式在某一個點處的導數
function derivative (f, delta)
delta = delta or 1e-4
return function (x)
return (f(x + delta) - f(x)) / delta
end
end
-- sin 的導數是 cos
c = derivative(math.sin)
print(math.sin(1), c(1))
print(math.sin(1), math.cos(0))
閉合函式
names = {"Pe", "Tu", "Me"}
grades = {Pe = 10, Tu = 5, Me = 8}
table.sort(names, function (x, y)
return grades[x] > grades[y]
end
)
-- 按照年級進行排序
print(names[1], names[2], names[3])
function sortByGrade(names, grades)
table.sort(names, function (x, y)
return grades[x] > grades[y]
end
)
end
sortByGrade(names, grades)
- 匿名函式中呼叫外部函式的形參的變數稱為非區域變數,
- 一個
closure就是一個一個函式加上該函式所需訪問的所有「非區域變數」 - 如果再次呼叫
newCounter,那么他會創建一個新的區域變數i從而也會得到一個新的closure
function newCounter()
local i = 0
return function ()
i = i + 1
return i
end
end
c1 = newCounter()
print(c1()) -- 1
print(c1()) -- 2
-- 重新定義 sin 函式,弧度轉為角度
oldSin = math.sin
math.sin = function (x)
return oldSin(x * math.pi / 180)
end
do
local oldSin = math.sin
local k = math.pi / 180
math.sin = function (x)
return oldSin(x * k)
end
end
-- 限制一個程式訪問檔案
do
local oldOpen = io.open
local access_OK = function (filename, mode)
-- <檢查訪問權限的代碼>
end
io.open = function (filename, mode)
if access_OK(filename, mode) then
print("允許訪問")
return oldOpen(filename, mode)
else
print("不允許訪問")
return nil, "access denied"
end
end
end
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/5315.html
標籤:其他
上一篇:lua學習之復習匯總篇
