如何编写接受任何数值类型的泛型函数?

来自JS / TS,我想结帐并制作一个简单的计算器,因为int和浮点数之间存在差异,因此编写需要任何数字的函数的首选方法是什么?


例如:


package main


func add(a float64, b float64) float64 {

  return a + b;

}


func main() {

  a := 1;

  b := 2;

  fmt.Println(add(1, 2)); // 3

  fmt.Println(add(a, b)); // cannot use a (type int) as type float64 in argument to add

  fmt.Println(add(1.5, 3.2)); // 4.7

  fmt.Println(add(2.5, 2)); // 4.5

}

我是否需要将所有内容转换为浮点型(因为它“覆盖”了int范围),或者我是否为每个类型创建一个单独的函数,例如和,或者可能有一种更优雅的方式?addInt(a int, b int) intaddFloat(a float64, b float64) float64


函数式编程
浏览 60回答 2
2回答

慕村225694

前往 1.18通过在 Go 1.18 中引入类型参数,这更容易实现。您可以定义 一个参数化的函数,并使用接口约束来限制为数值类型。TTfunc add[T Number](a, b T) T {    return a + b}可以使用 golang.org/x/exp/constraints 包(仍处于实验阶段)来定义约束:Numberimport "golang.org/x/exp/constraints"type Number interface {    constraints.Integer | constraints.Float}哪里:Number是 和 的类型集的并集constraints.Integerconstraints.Floatconstraints.Integer是所有有符号和无符号整数类型的集合contraints.Float是浮点型的集合这将允许您使用任意两个数值类型的参数进行调用。然后,在函数体中,您将能够使用约束中所有类型支持的任何操作。因此,对于数字,这也包括算术运算符。然后声明类似的函数很容易:addfunc multiply[T Number](a, b T) T {    return a * b}请记住,参数必须具有相同的类型。无论泛型如何,您都不能使用不同的类型;从规格运营商:[...]操作数类型必须相同,除非操作涉及移位或非类型化常量。因此,我们的泛型和函数仅使用一个类型参数定义。这意味着您也不能使用默认类型不兼容的非类型化常量调用函数:addmultiplyTaddadd(2.5, 2) // won't compile在这种情况下,编译器将从第一个参数推断出 的类型,该参数默认为 ,然后将无法匹配 的类型,该类型默认为 。T2.5float642int完整程序:package mainimport (    "fmt"    "golang.org/x/exp/constraints")type Number interface {    constraints.Integer | constraints.Float}func main() {    a := 1    b := 2        fmt.Println(add(1, 2))     // 3    fmt.Println(add(a, b))     // 3    fmt.Println(add(1.5, 3.2)) // 4.7    // fmt.Println(add(2.5, 2)) // default type int of 2 does not match inferred type float64 for T}func add[T Number](a, b T) T {    return a + b}游乐场: https://go.dev/play/p/rdqi3_-EdHp

catspeake

直到 Go 1.17(预泛型)。查看更新解决方案的其他答案最简单的选择是在调用站点上转换参数。add(float64(a), float64(b))
打开App,查看更多内容
随时随地看视频慕课网APP