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