GO如何模拟流操作实现示例探究

 更新时间:2024年01月05日 14:44:50   作者:小雷学编程 Jacksonlei  
这篇文章主要为大家介绍了GO如何模拟流操作实现示例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前言

本篇主要是做一个记录,希望对您有用

首先,你可能看到过类似的JAVA 代码如下 :

return Optional.ofNullable(list).flatMap(list -> list.stream()
                .filter(Objects::nonNull)
                .filter(i -> stockCode.equals(i.id()))
                .map(this::mathod)
                .findFirst())
.orElse(null);

时间有限我们今天尝试着模拟一下部分方法,感受一下。

集合

首先我们需要一个集合如下:

var okgoarch = List{
    "arm",
    "arm64",
    "loong64",
    "mips64",
    "mips64le",
    "ppc64",
    "riscv64",
    "sparc64",
}

过滤的方法

接下来我们需要尝试写一个过滤的方法这个方法应该要接受一个方法,并且这个方法的需要接受的类型应该是一个泛型类型,返回值是BOOL ,然后我们对集合的每个元素都操作,所以大概样子就出来:

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

可能有心细的朋友已经发现了 List 这个类,是我自己定义的,要是别的类型呢?往下看

type List []string

定个接口来处理通用类型

LIST 实际上就是我定义的类似,为了方便使用,这里有个问题,我如果定义的是别的类型是不是就不管用了,所以我们需要定个接口来处理通用类型,所以接口就出来了:

type Stream[T any] interface {
  Filter(pre Predicate[T]) bool
}

但是又有一个问题,如果别的类型实现的方法可能返回不是BOOL 怎么办,那么接口就长成下面这样,虽然不太可能为了实现拓展我还是愿意这么做,如下:

type Stream[T,  OUT any] interface {
  Filter(pre Predicate[T]) OUT
}

测试对字符串切片过滤的逻辑

到这里一个简单的对字符串切片过滤的逻辑就完成了,我们测试一下:

 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]

貌似还算成功过,接下来我尝试实现一个稍微复杂点的方法。

stream.map(()->{}) 等操作

定义一个方法结构

我们都知道MAP的流操作方法需要接受一个方法类型作为入参,GO函数式编程很好的解决了这个问题,首先我们需要先定义一个方法结构,它大概长这样:

type Function[F any, OUT any] func(n F) OUT

这里定义方法入参和出参都是泛型类型,我暂且认为MAP操作就是对集合的每个元素都进行一个方法操作,那么它的方法可能长这样:

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
}

完整接口

同样,如果是通用类型需要一个接口支持,不然切片可以用MAP,其他类型却不行,所以接口我们加一个定义,完整接口如下:

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
}

同样也要加上接口哦,字符串切片排序比较简单。到这里字符串切片的方法就定义完了

测试一下

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)

字符串切片可以,是否别的类型也可以

我尝试用了一个结构体切片来说明同样的思路我直接贴代码了:

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
}

以上代码是结构体切片类型的实现,结构体类型可以自己定义,例如JAVA某个子类型的stream 流接口的实现一样

完整代码

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如何模拟流操作实现示例探究的详细内容,更多关于GO模拟流操作的资料请关注脚本之家其它相关文章!

相关文章

  • Go Gin实现文件上传下载的示例代码

    Go Gin实现文件上传下载的示例代码

    这篇文章主要介绍了Go Gin实现文件上传下载的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 3个Go语言中实用重构技术分享

    3个Go语言中实用重构技术分享

    代码重构是在不改变外部功能的情况下对现有代码进行改进,是编程的核心部分之一,本文为大家介绍了Go语言中3个实用重构技术,需要的可以参考一下
    2023-06-06
  • go 协程返回值处理操作

    go 协程返回值处理操作

    这篇文章主要介绍了go 协程返回值处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Golang Copier入门到入坑探究

    Golang Copier入门到入坑探究

    这篇文章主要为大家介绍了Golang Copier入门到入坑探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Go语言学习之golang-jwt/jwt的教程分享

    Go语言学习之golang-jwt/jwt的教程分享

    jwt是 json web token的简称。go使用jwt目前,主流使用的jwt库是golang-jwt/jwt。本文就来和大家讲讲golang-jwt/jwt的具体使用,需要的可以参考一下
    2023-01-01
  • Go 语言选择器实例教程

    Go 语言选择器实例教程

    这篇文章主要为大家介绍了Go 语言选择器实例教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • Golang日志操作库zap的使用详解

    Golang日志操作库zap的使用详解

    zap 是 uber 开源的一个高性能,结构化,分级记录的日志记录包,本文主要为大家详细介绍了zap的具体使用,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • Go检查结构体中是否存在某个字段及创建结构体切片或映射

    Go检查结构体中是否存在某个字段及创建结构体切片或映射

    这篇文章主要为大家介绍了Go检查结构体中是否存在某个字段及创建结构体切片或映射实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Go语言规范context 类型的key用法示例解析

    Go语言规范context 类型的key用法示例解析

    这篇文章主要为大家介绍了Go语言规范context 类型的key用法示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Golang中切片的用法与本质详解

    Golang中切片的用法与本质详解

    Go的切片类型为处理同类型数据序列提供一个方便而高效的方式,下面这篇文章就来给大家介绍了关于Golang中切片的用法与本质的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-07-07

最新评论