GO如何模擬流操作實(shí)現(xiàn)示例探究
前言
本篇主要是做一個(gè)記錄,希望對(duì)您有用
首先,你可能看到過(guò)類似的JAVA 代碼如下 :
return Optional.ofNullable(list).flatMap(list -> list.stream() .filter(Objects::nonNull) .filter(i -> stockCode.equals(i.id())) .map(this::mathod) .findFirst()) .orElse(null);
時(shí)間有限我們今天嘗試著模擬一下部分方法,感受一下。
集合
首先我們需要一個(gè)集合如下:
var okgoarch = List{ "arm", "arm64", "loong64", "mips64", "mips64le", "ppc64", "riscv64", "sparc64", }
過(guò)濾的方法
接下來(lái)我們需要嘗試寫(xiě)一個(gè)過(guò)濾的方法這個(gè)方法應(yīng)該要接受一個(gè)方法,并且這個(gè)方法的需要接受的類型應(yīng)該是一個(gè)泛型類型,返回值是BOOL ,然后我們對(duì)集合的每個(gè)元素都操作,所以大概樣子就出來(lái):
func (ls List) Filter(fk Predicate[string]) List { if fk == nil { return nil } var res List for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } type Predicate[P any] func(n P) bool
可能有心細(xì)的朋友已經(jīng)發(fā)現(xiàn)了 List 這個(gè)類,是我自己定義的,要是別的類型呢?往下看
type List []string
定個(gè)接口來(lái)處理通用類型
LIST 實(shí)際上就是我定義的類似,為了方便使用,這里有個(gè)問(wèn)題,我如果定義的是別的類型是不是就不管用了,所以我們需要定個(gè)接口來(lái)處理通用類型,所以接口就出來(lái)了:
type Stream[T any] interface { Filter(pre Predicate[T]) bool }
但是又有一個(gè)問(wèn)題,如果別的類型實(shí)現(xiàn)的方法可能返回不是BOOL 怎么辦,那么接口就長(zhǎng)成下面這樣,雖然不太可能為了實(shí)現(xiàn)拓展我還是愿意這么做,如下:
type Stream[T, OUT any] interface { Filter(pre Predicate[T]) OUT }
測(cè)試對(duì)字符串切片過(guò)濾的邏輯
到這里一個(gè)簡(jiǎn)單的對(duì)字符串切片過(guò)濾的邏輯就完成了,我們測(cè)試一下:
var okgoarch = List{ "arm", "arm64", "loong64", "mips64", "mips64le", "ppc64", "riscv64", "sparc64", } lss := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }) fmt.Printf("%+v\n", lss) //[mips64le sparc64]
貌似還算成功過(guò),接下來(lái)我嘗試實(shí)現(xiàn)一個(gè)稍微復(fù)雜點(diǎn)的方法。
stream.map(()->{}) 等操作
定義一個(gè)方法結(jié)構(gòu)
我們都知道MAP的流操作方法需要接受一個(gè)方法類型作為入?yún)?,GO函數(shù)式編程很好的解決了這個(gè)問(wèn)題,首先我們需要先定義一個(gè)方法結(jié)構(gòu),它大概長(zhǎng)這樣:
type Function[F any, OUT any] func(n F) OUT
這里定義方法入?yún)⒑统鰠?/strong>都是泛型類型,我暫且認(rèn)為MAP操作就是對(duì)集合的每個(gè)元素都進(jìn)行一個(gè)方法操作,那么它的方法可能長(zhǎng)這樣:
func (ls List) Map(fk Function[string, string]) List { if fk == nil { return nil } var res List for _, nod := range ls { res = append(res, fk(nod)) } return res }
完整接口
同樣,如果是通用類型需要一個(gè)接口支持,不然切片可以用MAP,其他類型卻不行,所以接口我們加一個(gè)定義,完整接口如下:
type Stream[T, F2, OUT any] interface {</code><code> Filter(pre Predicate[T]) OUT</code><code> Map(function Function[T, F2]) OUT</code><code>}
按照上面同樣的方法我定義了Sorted 方法和 字符串Joins方法,如下 :
type Stream[T, F2, OUT any] interface { Filter(pre Predicate[T]) OUT Map(function Function[T, F2]) OUT }
同樣也要加上接口哦,字符串切片排序比較簡(jiǎn)單。到這里字符串切片的方法就定義完了
測(cè)試一下
ls := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }). Map(strings.ToTitle). Sorted(). //按照ascii碼表排序 joins(":") fmt.Printf("%+v\n", [arm arm64 loong64 mips64 mips64le ppc64 riscv64 sparc64] ls)
字符串切片可以,是否別的類型也可以
我嘗試用了一個(gè)結(jié)構(gòu)體切片來(lái)說(shuō)明同樣的思路我直接貼代碼了:
type Person struct { Name string Age int } type ByAgeNameCompare []Person func (a ByAgeNameCompare) Len() int { return len(a) } func (a ByAgeNameCompare) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByAgeNameCompare) Less(i, j int) bool { if a[i].Age == a[j].Age { return a[i].Name < a[j].Name //DESC } return a[i].Age < a[j].Age //ASC } type Persons []Person func (ls Persons) Sorted() Persons { sort.Sort(ByAgeNameCompare(ls)) return ls } func (ls Persons) Filter(fk Predicate[Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } func (ls Persons) Map(fk Function[Person, any]) any { if fk == nil { return nil } var res []any for _, nod := range ls { res = append(res, fk(nod)) } return res } func (ls Persons) Map1(fk Function[Person, Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { res = append(res, fk(nod)) } return res }
以上代碼是結(jié)構(gòu)體切片類型的實(shí)現(xiàn),結(jié)構(gòu)體類型可以自己定義,例如JAVA某個(gè)子類型的stream 流接口的實(shí)現(xiàn)一樣
完整代碼
type Predicate[P any] func(n P) bool type Function[F any, OUT any] func(n F) OUT type List []string type Stream[T, F2, OUT any] interface { Filter(pre Predicate[T]) OUT Map(function Function[T, F2]) OUT Sorted() OUT } func (ls List) Filter(fk Predicate[string]) List { if fk == nil { return nil } var res List for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } func (ls List) Map(fk Function[string, string]) List { if fk == nil { return nil } var res List for _, nod := range ls { res = append(res, fk(nod)) } return res } func (ls List) joins(delim string) string { return strings.Join(ls, delim) } func (ls List) Sorted() List { sort.Strings(ls) return ls } type Person struct { Name string Age int } type ByAgeNameCompare []Person func (a ByAgeNameCompare) Len() int { return len(a) } func (a ByAgeNameCompare) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a ByAgeNameCompare) Less(i, j int) bool { if a[i].Age == a[j].Age { return a[i].Name < a[j].Name //DESC } return a[i].Age < a[j].Age //ASC } type Persons []Person func (ls Persons) Sorted() Persons { sort.Sort(ByAgeNameCompare(ls)) return ls } func (ls Persons) Filter(fk Predicate[Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { if fk(nod) { res = append(res, nod) } } return res } func (ls Persons) Map(fk Function[Person, any]) any { if fk == nil { return nil } var res []any for _, nod := range ls { res = append(res, fk(nod)) } return res } func (ls Persons) Map1(fk Function[Person, Person]) Persons { if fk == nil { return nil } var res Persons for _, nod := range ls { res = append(res, fk(nod)) } return res } func main() { var okgoarch = List{ "arm", "arm64", "loong64", "mips64", "mips64le", "ppc64", "riscv64", "sparc64", } lss := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }) fmt.Printf("%+v\n", lss) fmt.Printf("%+v\n", okgoarch) ls := okgoarch. Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }). Map(strings.ToTitle). Sorted(). //按照ascii碼表排序 joins(":") fmt.Printf("%+v\n", ls) peoples := Persons{ {"Alice", 30}, {"Bob", 25}, {"Charlie", 35}, {"Dark", 75}, } psvar := peoples. Filter(func(n Person) bool { return n.Name != "Charlie" }). Map(func(n Person) any { return n.Name }) fmt.Printf("%+v\n", psvar) psvar1 := peoples. Filter(func(n Person) bool { return n.Name != "Charlie" }). Map1(func(n Person) Person { n.Name = n.Name + "pick" return n }).Sorted() fmt.Printf("%+v", psvar1) } [mips64le sparc64] [arm arm64 loong64 mips64 mips64le ppc64 riscv64 sparc64] MIPS64LE:SPARC64 [Alice Bob Dark] [{Name:Bobpick Age:25} {Name:Alicepick Age:30} {Name:Darkpick Age:75}]
以上就是GO如何模擬流操作實(shí)現(xiàn)示例探究的詳細(xì)內(nèi)容,更多關(guān)于GO模擬流操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang使用協(xié)程實(shí)現(xiàn)批量獲取數(shù)據(jù)
服務(wù)端經(jīng)常需要返回一個(gè)列表,里面包含很多用戶數(shù)據(jù),常規(guī)做法當(dāng)然是遍歷然后讀緩存。使用Go語(yǔ)言后,可以并發(fā)獲取,極大提升效率,本文就來(lái)聊聊具體的實(shí)現(xiàn)方法,希望對(duì)大家有所幫助2023-02-02一篇文章帶你搞懂Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)Time
在我們開(kāi)發(fā)的過(guò)程中,每個(gè)項(xiàng)目都需要時(shí)間這一類的函數(shù),此時(shí)對(duì)time這個(gè)包的研究深度就顯得尤為重要,這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章帶你搞懂Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)Time的相關(guān)資料,需要的朋友可以參考下2022-10-10Go語(yǔ)言輕量級(jí)高性能嵌入式規(guī)則引擎RuleGo使用詳解
這篇文章主要為大家介紹了Go語(yǔ)言輕量級(jí)高性能嵌入式規(guī)則引擎RuleGo使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11Go并發(fā)編程中的錯(cuò)誤恢復(fù)機(jī)制與代碼持續(xù)執(zhí)行實(shí)例探索
這篇文章主要為大家介紹了Go并發(fā)編程中的錯(cuò)誤恢復(fù)機(jī)制與代碼持續(xù)執(zhí)行實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01如何在Go語(yǔ)言中靈活運(yùn)用匿名函數(shù)和閉包
這篇文章主要為大家介紹了如何在Go語(yǔ)言中靈活運(yùn)用匿名函數(shù)和閉包實(shí)現(xiàn)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10