Golang函數(shù)式編程深入分析實例
定義集合功能函數(shù)
首先定義用于測試的結(jié)構(gòu)體WorkWith
:
// WorkWith is the struct we'll // be implementing collections for type WorkWith struct { Data string Version int }
針對該結(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 }
實現(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 } }
上面定義了三個函數(shù),LowerCaseData修改WorkWith中Data值為小寫形式,IncrementVersion讓WorkWith中版本增加1,OldVersion基于參數(shù)過濾版本。
測試集合功能
定義測試用例文件:
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) }
運行 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對象,這遵循函數(shù)式編程思想,盡可能讓函數(shù)純粹:不修改原集合元素,即對原集合無副作用,而是生成新的集合。如果需要對集合應用多個功能,那么這種模式能夠省去很多麻煩,并且測試也很簡單。我們還可以將映射和過濾器鏈接在一起,讓代碼更簡潔可讀。
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ù)定義為集合類型的方法,并返回集合類型,則上述代碼會更優(yōu)雅。
泛型實現(xiàn)
上面代碼僅能在特定類型上使用,我們自然想實現(xiàn)泛型函數(shù),下面通過一個簡單示例進行說明:
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,當然兩者類型也可以一樣。下面測試函數(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ù)式編程深入分析實例的文章就介紹到這了,更多相關(guān)Go函數(shù)式編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Golang初始化MySQL數(shù)據(jù)庫方法淺析
這篇文章主要介紹了Golang初始化MySQL數(shù)據(jù)庫的方法,數(shù)據(jù)庫的建立第一步即要初始化,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-05-05golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型
這篇文章主要介紹了golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12Golang之sync.Pool對象池對象重用機制總結(jié)
這篇文章主要對Golang的sync.Pool對象池對象重用機制做了一個總結(jié),文中有相關(guān)的代碼示例和圖解,具有一定的參考價值,需要的朋友可以參考下2023-07-07