日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

lua 字符串分割_Lua函数式编程(中)

發(fā)布時間:2023/12/9 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lua 字符串分割_Lua函数式编程(中) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

書接前文,我們繼續(xù)慢慢的了解 所謂的函數(shù)式編程思想??疾橄旅娴睦?/p>判斷給定的數(shù)是否是偶數(shù)

在Lua里面這似乎是個幼兒園問題

local isEven = function(v) return v % 2 == 0 end

但我們如何用函數(shù)式的思維去解決問題?是的,假設我們有了以下函數(shù)

R.mod -- 求余數(shù) R.equals -- 判斷是否相等

我們?yōu)楹我略煲粋€函數(shù)輪子呢?有什么辦法可以重復利用已有的函數(shù)算法呢?

函數(shù)組合

最強大的函數(shù)式編程核武器出現(xiàn)了。這就是函數(shù)組合,但是理解這個概念一點都不困難,就像是數(shù)學中的函數(shù)一樣

y = f(x) , z = g(y) = g(f(x)) h = ComposeMagic(f, g) //考慮將f函數(shù)和g函數(shù)進行組合 z = h(x) //這樣可以直接得到最終結果

函數(shù)組合就像一個管道一樣,假想一組數(shù)據(jù)要經過f g h三個函數(shù)的加工,變成最終我們需要的數(shù)據(jù)

values -> f() -> g() -> h() -> results

那么中間的函數(shù)實際上可以經由compose組合,變成一個函數(shù)算法

values -> composed() -> results

這個就是函數(shù)組合的思維核心,經由函數(shù)自身的邏輯操作,而非針對值的操作,因此可以充分的利用諸多已經實現(xiàn)好的小函數(shù)、小算法、小輪子,自由組合而成為我們需求的算法

是時候用函數(shù)式思想實現(xiàn)之前的那個算法了

local isEven = R.compose(R.equals(0), R.mod(2))

compose方案會組合后面的函數(shù),使其從后往前依次接收數(shù)據(jù)、返回處理結果。

number -> R.mod(2) 求得余數(shù) -> 返回結果 -> R.equals(0) 判斷是否與0相等 -> 返回結果

不過這對于這個算法來說確實大材小用了,但是這其中的思想還是值得我們研習的。來看個復雜點的例子

實現(xiàn)一個算法,將IP4的地址轉換為一個Int32的數(shù)

我們先看傳統(tǒng)的實現(xiàn)(其中仍然借助了R.split方法,我們就當成一個傳統(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

這個實現(xiàn)的確不怎么好看,而且還要注意他的約定是 big-endian,如果修改成little-endian,我們得鉆到函數(shù)細節(jié)里面去想辦法。

讓我們體會下函數(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)

如果想實現(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) 對列表中的每個元素進行tonumber轉換 -> {192, 168, 1, 1} -> R.reduce(offset, 0) 每兩個元素執(zhí)行一次offset操作,將列表合并為一個Int32數(shù)字 -> 3232235777

而且欣慰的是,過程中的中間函數(shù),都可以作為其他算法的子函數(shù)繼續(xù)組合使用,函數(shù)組合充分的解放了對造輪子的沖動,這就是函數(shù)編程思想的核心魅力。

副作用(Side Effect)和不可變(Immutable)

什么是函數(shù)?經典的Pascal語言有兩個關鍵字,很好的區(qū)分了函數(shù)和過程

function --> 給定輸入,經過函數(shù)算法,返回給定的輸出;相同的輸入永遠返回相同的輸出,沒有副作用。 procedure --> 給定輸入,經過過程算法,改變某些狀態(tài),有副作用。

在函數(shù)式編程思維中,function必須的純凈的,無副作用的,其特性為

  • 不依賴全局變量
  • 不修改函數(shù)參數(shù)
  • 不修改任何狀態(tài)(db、io、網絡、標準輸出、對象等等)
  • 只要輸入一樣,輸出必定一樣
  • 這些特性使得函數(shù)具有了非常誘人的特性

  • 可測試性(只需要給定參數(shù)就能判定這個函數(shù)是否工作正常,不需要Mock任何對象系統(tǒng))
  • 可緩存性(只要參數(shù)一樣,就返回一樣的內容,很容易緩存算法結果)
  • 可并發(fā)性(沒有副作用,沒任何數(shù)據(jù)競爭,多線程跑跑算法,安全的很)
  • 自解釋性(描述參數(shù)和返回值即可,不用考慮任何外部系統(tǒng)知識)
  • 引用透明(可以在算法中將函數(shù)調用替換為他的結果)
  • 但是很遺憾,本文無法做深入展開(您可以參考任何一篇介紹函數(shù)式編程思想的文章)

    純凈的函數(shù)使得傳入的參數(shù)被安全的保護起來,你不希望你的列表傳入一個算法,然后被這個算法破壞的亂七八糟吧。

    local list = {1,2,3} R.append(4, list) --> list 仍然是1,2,3 這種保障去掉了相當多對引用做修改而導致的Bug

    下一篇我們會就性能、函數(shù)簽名做一番探討,有興趣的可以繼續(xù)關注。

    謝謝閱讀。

    總結

    以上是生活随笔為你收集整理的lua 字符串分割_Lua函数式编程(中)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。