Golang函數(shù)式編程深入分析實(shí)例
定義集合功能函數(shù)
首先定義用于測(cè)試的結(jié)構(gòu)體WorkWith
:
// WorkWith is the struct we'll // be implementing collections for type WorkWith struct { Data string Version int }
針對(duì)該結(jié)構(gòu)體定義filter和map函數(shù):
// 基于判斷函數(shù)過濾集合,返回符合條件的集合元素 func Filter(ws []WorkWith, f func(w WorkWith) bool) []WorkWith { // depending on results, smaller size for result // is len == 0 result := make([]WorkWith, 0) for _, w := range ws { if f(w) { result = append(result, w) } } return result } // 基于轉(zhuǎn)換函數(shù)轉(zhuǎn)換集合元素,返回集合的元素為轉(zhuǎn)換后的元素 func Map(ws []WorkWith, f func(w WorkWith) WorkWith) []WorkWith { // the result should always be the same // length result := make([]WorkWith, len(ws)) for pos, w := range ws { newW := f(w) result[pos] = newW } return result }
實(shí)現(xiàn)具體功能函數(shù)
import "strings" // LowerCaseData does a ToLower to the // Data string of a WorkWith func LowerCaseData(w WorkWith) WorkWith { w.Data = strings.ToLower(w.Data) return w } // IncrementVersion increments a WorkWiths // Version func IncrementVersion(w WorkWith) WorkWith { w.Version++ return w } // OldVersion returns a closures // that validates the version is greater than // the specified amount func OldVersion(v int) func(w WorkWith) bool { return func(w WorkWith) bool { return w.Version >= v } }
上面定義了三個(gè)函數(shù),LowerCaseData修改WorkWith中Data值為小寫形式,IncrementVersion讓W(xué)orkWith中版本增加1,OldVersion基于參數(shù)過濾版本。
測(cè)試集合功能
定義測(cè)試用例文件:
import ( "fmt" "testing" ) func TestMap(t *testing.T) { ws := []WorkWith{ {"Example", 1}, {"Example 2", 2}, } fmt.Printf("Initial list: %#v\n", ws) // first lower case the list ws = Map(ws, LowerCaseData) fmt.Printf("After LowerCaseData Map: %#v\n", ws) // next increment all versions ws = Map(ws, IncrementVersion) fmt.Printf("After IncrementVersion Map: %#v\n", ws) // lastly remove all versions older than 3 ws = Filter(ws, OldVersion(3)) fmt.Printf("After OldVersion Filter: %#v\n", ws) }
運(yùn)行 go test . -v
輸出結(jié)果如下:
Initial list: []collections.WorkWith{collections.WorkWith{Data:"Example", Version:1}, collections.WorkWith{Data:"Example 2", Version:2}}
After LowerCaseData Map: []collections.WorkWith{collections.WorkWith{Data:"example", Version:1}, collections.WorkWith{Data:"example 2", Version:2}}
After IncrementVersion Map: []collections.WorkWith{collections.WorkWith{Data:"example", Version:2}, collections.WorkWith{Data:"example 2", Version:3}}
After OldVersion Filter: []collections.WorkWith{collections.WorkWith{Data:"example 2", Version:3}}
上面示例中,我們注意到函數(shù)都沒有返回任何error對(duì)象,這遵循函數(shù)式編程思想,盡可能讓函數(shù)純粹:不修改原集合元素,即對(duì)原集合無(wú)副作用,而是生成新的集合。如果需要對(duì)集合應(yīng)用多個(gè)功能,那么這種模式能夠省去很多麻煩,并且測(cè)試也很簡(jiǎn)單。我們還可以將映射和過濾器鏈接在一起,讓代碼更簡(jiǎn)潔可讀。
ws := []WorkWith{ {"Example", 1}, {"Example 2", 2}, } fmt.Printf("Initial list: %#v\n", ws) result := Filter(Map(Map(ws, LowerCaseData), IncrementVersion), OldVersion(3)) fmt.Printf("After OldVersion Filter: %#v\n", result)
如果功能函數(shù)定義為集合類型的方法,并返回集合類型,則上述代碼會(huì)更優(yōu)雅。
泛型實(shí)現(xiàn)
上面代碼僅能在特定類型上使用,我們自然想實(shí)現(xiàn)泛型函數(shù),下面通過一個(gè)簡(jiǎn)單示例進(jìn)行說明:
func map2[T, U any](data []T, f func(T) U) []U { res := make([]U, 0, len(data)) for _, e := range data { res = append(res, f(e)) } return res }
該函數(shù)接收類型T,轉(zhuǎn)換后返回類型U,當(dāng)然兩者類型也可以一樣。下面測(cè)試函數(shù)功能:
// 字符串轉(zhuǎn)大寫 words := []string{"war", "cup", "water", "tree", "storm"} result := map2(words, func(s string) string { return strings.ToUpper(s) }) fmt.Println(result) // 生成原集合元素的平方集合 fmt.Println("-------------------") numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} squares := map2(numbers, func(n int) int { return n * n }) fmt.Println(squares) // 數(shù)值轉(zhuǎn)為字符串 fmt.Println("-------------------") as_strings := map2(numbers, func(n int) string { return strconv.Itoa(n) }) fmt.Printf("%q", as_strings)
到此這篇關(guān)于Golang函數(shù)式編程深入分析實(shí)例的文章就介紹到這了,更多相關(guān)Go函數(shù)式編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言學(xué)習(xí)教程之聲明語(yǔ)法(譯)
Golang 就是類C的語(yǔ)法,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言學(xué)習(xí)教程之聲明語(yǔ)法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11Go語(yǔ)言O(shè)RM框架構(gòu)造查詢條件示例詳解
這篇文章主要為大家介紹了Go語(yǔ)言O(shè)RM框架構(gòu)造查詢條件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議
錯(cuò)誤處理在每個(gè)語(yǔ)言中都是一項(xiàng)重要內(nèi)容,眾所周知,通常寫程序時(shí)遇到的分為異常與錯(cuò)誤兩種,Golang中也不例外,這篇文章主要給大家介紹了一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議,需要的朋友可以參考下2021-09-09Golang初始化MySQL數(shù)據(jù)庫(kù)方法淺析
這篇文章主要介紹了Golang初始化MySQL數(shù)據(jù)庫(kù)的方法,數(shù)據(jù)庫(kù)的建立第一步即要初始化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-05-05Go語(yǔ)言學(xué)習(xí)之goroutine詳解
Goroutine是建立在線程之上的輕量級(jí)的抽象。它允許我們以非常低的代價(jià)在同一個(gè)地址空間中并行地執(zhí)行多個(gè)函數(shù)或者方法,這篇文章主要介紹了Go語(yǔ)言學(xué)習(xí)之goroutine的相關(guān)知識(shí),需要的朋友可以參考下2020-02-02golang語(yǔ)言如何將interface轉(zhuǎn)為int, string,slice,struct等類型
這篇文章主要介紹了golang語(yǔ)言如何將interface轉(zhuǎn)為int, string,slice,struct等類型,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Golang之sync.Pool對(duì)象池對(duì)象重用機(jī)制總結(jié)
這篇文章主要對(duì)Golang的sync.Pool對(duì)象池對(duì)象重用機(jī)制做了一個(gè)總結(jié),文中有相關(guān)的代碼示例和圖解,具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07Golang使用WebSocket通信的實(shí)現(xiàn)
這篇文章主要介紹了Golang使用WebSocket通信的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02