lua 字符串分割_Lua函数式编程(中)
書接前文,我們繼續慢慢的了解 所謂的函數式編程思想。考查下面的例子
判斷給定的數是否是偶數在Lua里面這似乎是個幼兒園問題
local isEven = function(v) return v % 2 == 0 end但我們如何用函數式的思維去解決問題?是的,假設我們有了以下函數
R.mod -- 求余數 R.equals -- 判斷是否相等我們為何要新造一個函數輪子呢?有什么辦法可以重復利用已有的函數算法呢?
函數組合
最強大的函數式編程核武器出現了。這就是函數組合,但是理解這個概念一點都不困難,就像是數學中的函數一樣
y = f(x) , z = g(y) = g(f(x)) h = ComposeMagic(f, g) //考慮將f函數和g函數進行組合 z = h(x) //這樣可以直接得到最終結果函數組合就像一個管道一樣,假想一組數據要經過f g h三個函數的加工,變成最終我們需要的數據
values -> f() -> g() -> h() -> results那么中間的函數實際上可以經由compose組合,變成一個函數算法
values -> composed() -> results這個就是函數組合的思維核心,經由函數自身的邏輯操作,而非針對值的操作,因此可以充分的利用諸多已經實現好的小函數、小算法、小輪子,自由組合而成為我們需求的算法
是時候用函數式思想實現之前的那個算法了
local isEven = R.compose(R.equals(0), R.mod(2))compose方案會組合后面的函數,使其從后往前依次接收數據、返回處理結果。
number -> R.mod(2) 求得余數 -> 返回結果 -> R.equals(0) 判斷是否與0相等 -> 返回結果不過這對于這個算法來說確實大材小用了,但是這其中的思想還是值得我們研習的。來看個復雜點的例子
實現一個算法,將IP4的地址轉換為一個Int32的數我們先看傳統的實現(其中仍然借助了R.split方法,我們就當成一個傳統方法來使用)
local function convertIp2Int(ip)local ip_numbers = R.split(".", ip)local result = 0local offset = 1for i, ipn in ipairs(ip_numbers) doresult = result + tonumber(ipn) * offsetoffset = offset * 256endreturn result end這個實現的確不怎么好看,而且還要注意他的約定是 big-endian,如果修改成little-endian,我們得鉆到函數細節里面去想辦法。
讓我們體會下函數組合的強大吧。先看看最終實現
local split = R.split(".") local parse = R.map(tonumber) local offset = function(f, s) return f * 256 + s end local convertIp2Int = R.compose(R.reduce(offset, 0), parse, R.reverse, split)如果想實現little-endian版本的,只需要移除組合函數中的R.reverse方法即可,基于原題目,我們可以簡化一下
local offset = function(f, s) return f * 256 + s end local convertIp2Int = R.compose(R.reduce(offset, 0), R.map(tonumber), R.split('.'))數據流向如下
"192.168.1.1" -> R.split('.') 分割字符串 -> {"192","168","1","1"} -> R.map(tonumber) 對列表中的每個元素進行tonumber轉換 -> {192, 168, 1, 1} -> R.reduce(offset, 0) 每兩個元素執行一次offset操作,將列表合并為一個Int32數字 -> 3232235777而且欣慰的是,過程中的中間函數,都可以作為其他算法的子函數繼續組合使用,函數組合充分的解放了對造輪子的沖動,這就是函數編程思想的核心魅力。
副作用(Side Effect)和不可變(Immutable)
什么是函數?經典的Pascal語言有兩個關鍵字,很好的區分了函數和過程
function --> 給定輸入,經過函數算法,返回給定的輸出;相同的輸入永遠返回相同的輸出,沒有副作用。 procedure --> 給定輸入,經過過程算法,改變某些狀態,有副作用。在函數式編程思維中,function必須的純凈的,無副作用的,其特性為
這些特性使得函數具有了非常誘人的特性
但是很遺憾,本文無法做深入展開(您可以參考任何一篇介紹函數式編程思想的文章)
純凈的函數使得傳入的參數被安全的保護起來,你不希望你的列表傳入一個算法,然后被這個算法破壞的亂七八糟吧。
local list = {1,2,3} R.append(4, list) --> list 仍然是1,2,3 這種保障去掉了相當多對引用做修改而導致的Bug下一篇我們會就性能、函數簽名做一番探討,有興趣的可以繼續關注。
謝謝閱讀。
總結
以上是生活随笔為你收集整理的lua 字符串分割_Lua函数式编程(中)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux按数量复制文件,linux下d
- 下一篇: Apache 2.0性能优化—MPM的选