Golang函數式編程深入分析實例
定義集合功能函數
首先定義用于測試的結構體WorkWith:
// WorkWith is the struct we'll
// be implementing collections for
type WorkWith struct {
Data string
Version int
}
針對該結構體定義filter和map函數:
// 基于判斷函數過濾集合,返回符合條件的集合元素
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
}
// 基于轉換函數轉換集合元素,返回集合的元素為轉換后的元素
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)具體功能函數
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
}
}
上面定義了三個函數,LowerCaseData修改WorkWith中Data值為小寫形式,IncrementVersion讓WorkWith中版本增加1,OldVersion基于參數過濾版本。
測試集合功能
定義測試用例文件:
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
輸出結果如下:
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}}
上面示例中,我們注意到函數都沒有返回任何error對象,這遵循函數式編程思想,盡可能讓函數純粹:不修改原集合元素,即對原集合無副作用,而是生成新的集合。如果需要對集合應用多個功能,那么這種模式能夠省去很多麻煩,并且測試也很簡單。我們還可以將映射和過濾器鏈接在一起,讓代碼更簡潔可讀。
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)
如果功能函數定義為集合類型的方法,并返回集合類型,則上述代碼會更優(yōu)雅。
泛型實現(xiàn)
上面代碼僅能在特定類型上使用,我們自然想實現(xià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
}
該函數接收類型T,轉換后返回類型U,當然兩者類型也可以一樣。下面測試函數功能:
// 字符串轉大寫
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)
// 數值轉為字符串
fmt.Println("-------------------")
as_strings := map2(numbers, func(n int) string {
return strconv.Itoa(n)
})
fmt.Printf("%q", as_strings)
到此這篇關于Golang函數式編程深入分析實例的文章就介紹到這了,更多相關Go函數式編程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
CSP communicating sequential processes并發(fā)模型
這篇文章主要為大家介紹了CSP communicating sequential processes并發(fā)模型,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05
VScode下配置Go語言開發(fā)環(huán)境(2023最新)
在VSCode中配置Golang開發(fā)環(huán)境是非常簡單的,本文主要記錄了Go的安裝,以及給vscode配置Go的環(huán)境,具有一定的參考價值,感興趣的可以了解一下2023-10-10
搭建Go語言的ORM框架Gorm的具體步驟(從Java到go)
很多朋友不知道如何使用Goland軟件,搭建一個ORM框架GORM,今天小編給大家分享一篇教程關于搭建Go語言的ORM框架Gorm的具體步驟(從Java到go),感興趣的朋友跟隨小編一起學習下吧2022-09-09
golang 調用c語言動態(tài)庫方式實現(xiàn)
本文主要介紹了golang 調用c語言動態(tài)庫方式實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12

