Golang函數(shù)式編程深入分析實(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
}
實(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ù)過濾版本。
測試集合功能
定義測試用例文件:
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對象,這遵循函數(shù)式編程思想,盡可能讓函數(shù)純粹:不修改原集合元素,即對原集合無副作用,而是生成新的集合。如果需要對集合應(yīng)用多個(gè)功能,那么這種模式能夠省去很多麻煩,并且測試也很簡單。我們還可以將映射和過濾器鏈接在一起,讓代碼更簡潔可讀。
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)雅。
泛型實(shí)現(xiàn)
上面代碼僅能在特定類型上使用,我們自然想實(shí)現(xiàn)泛型函數(shù),下面通過一個(gè)簡單示例進(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)然兩者類型也可以一樣。下面測試函數(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議
錯(cuò)誤處理在每個(gè)語言中都是一項(xiàng)重要內(nèi)容,眾所周知,通常寫程序時(shí)遇到的分為異常與錯(cuò)誤兩種,Golang中也不例外,這篇文章主要給大家介紹了一些關(guān)于Go程序錯(cuò)誤處理的相關(guān)建議,需要的朋友可以參考下2021-09-09
Golang初始化MySQL數(shù)據(jù)庫方法淺析
這篇文章主要介紹了Golang初始化MySQL數(shù)據(jù)庫的方法,數(shù)據(jù)庫的建立第一步即要初始化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-05-05
golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型
這篇文章主要介紹了golang語言如何將interface轉(zhuǎn)為int, string,slice,struct等類型,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Golang之sync.Pool對象池對象重用機(jī)制總結(jié)
這篇文章主要對Golang的sync.Pool對象池對象重用機(jī)制做了一個(gè)總結(jié),文中有相關(guān)的代碼示例和圖解,具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07
Golang使用WebSocket通信的實(shí)現(xiàn)
這篇文章主要介紹了Golang使用WebSocket通信的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02

