GO中的通用编程简介:过滤和求和数字类型
#linux #go #generics #genericsprogramming

go是一种具有严格类型系统的静态键入语言,这意味着每个变量和函数参数必须具有在编译时定义的特定类型。虽然这使得GO程序快速有效,但它也可以使它们更加灵活和更难编写。为了解决此问题,GO 1.18引入了对仿制药的支持,允许程序员编写可以与多种类型一起使用的代码。

在本教程中,我们将探讨如何使用仿制药实现与数字类型一起使用的滤波器功能。我们的过滤器功能将根据是否应包含在过滤后的列表中包含一个值的值列表和谓词函数,该函数返回真或错误。此外,我们的过滤功能将返回过滤值的总和。

步骤1:定义数字接口

要实现我们的过滤器函数,我们将定义一个数字接口必须满足的数字接口。数字接口将具有两种方法:add and iSzero。添加方法将采用另一个值并返回两个值的总和,而如果值为零,则ISZERO方法将返回true。

type Numeric interface {
    Add(x interface{}) Numeric
    IsZero() bool
}

我们将使用接口{}键入定义添加方法的参数类型,这将使​​我们能够将任何类型的值传递给该方法。

步骤2:实现数字类型

接下来,我们将实施满足数字接口的两个数字类型:int和float。 int类型将是实现add和iszero方法的整数类型,而浮点类型将是浮点类型,也将实现add和iszero方法。

type Int int

func (i Int) Add(x interface{}) Numeric {
    switch x := x.(type) {
    case Int:
        return i + x
    }
    return nil
}

func (i Int) IsZero() bool {
    return i == 0
}

type Float float64

func (f Float) Add(x interface{}) Numeric {
    switch x := x.(type) {
    case Float:
        return f + x
    }
    return nil
}

func (f Float) IsZero() bool {
    return f == 0.0
}

两种类型的添加方法都使用类型开关来确定参数的类型,如果参数与接收者相同的类型,则返回两个值的总和。否则,它将返回零。

步骤3:实现过滤器功能

现在我们定义了数字接口并实现了int和float类型,我们可以使用它们来实现我们的过滤器功能。过滤器函数将值列表和谓词函数作为输入,并返回过滤列表和过滤值的总和。

func Filter[T Numeric](list []T, predicate func(T) bool) ([]T, T) {
    var result []T
    var sum T
    for _, item := range list {
        if predicate(item) {
            result = append(result, item)
            if sum.IsZero() {
                sum = item
            } else {
                sum = sum.Add(item).(T)
            }
        }
    }
    return result, sum
}

滤波器函数使用类型参数t,该类型由数字接口约束,以指定列表参数中的值类型。谓词函数将T型的单个值作为输入,并返回真或错误。

在函数内部,我们初始化了两个变量:结果,这是一个空的t和sum,它是初始化为T型T的零值。然后,我们循环遍历列表中的每个项目,并检查谓词是否该项目的功能返回true。

如果谓词函数返回true,我们将项目附加到结果切片中,并使用数字接口中定义的添加方法将其添加到总和的当前值。

我们还使用ISZERO方法来检查当前值是T型的初始零值还是已更新为非零值。最后,我们返回过滤后的结果切片和过滤项目的总和。此实现使我们可以将过滤器函数与实现数字接口的任何类型一起使用,从而为过滤和求和列表的元素提供了灵活且可重复使用的解决方案。

额外

一个更简单的解释

所以想象一下您有很多数字,您想找到哪个数字(可除以2),也可以找到这些偶数数字的总和。

在我们的程序中,我们创建了一个名为“过滤器”的函数,该函数列出了数字列表,并且可以过滤这些数字。过滤器函数返回两件事:符合条件的数字的过滤列表以及这些过滤数字的总和。

我们还创建了一种称为数字的类型,该类型表示任何数字数据类型,例如INT,Float等。此类型具有两种方法:add and Iszero。添加方法接收另一个数字值并返回两个值的总和。 ISZERO方法检查值是否等于零。

现在,让我们回到过滤器功能。在函数内部,我们初始化了两个变量:结果是与输入列表相同类型的空列表,并将其初始化为与输入列表相同类型的零值。然后,我们循环浏览输入列表中的每个项目,并检查该项目是否符合谓词功能指定的条件。如果确实如此,我们将其添加到我们的结果列表中,并使用add方法将其添加到我们的总和变量中。

在循环的末尾,我们返回结果列表和总和变量,该列表分别为我们提供了过滤列表和过滤数字的总和。

演示代码演练