define generic type by using int

2023-06-27  本文已影响0人  9_SooHyun

define generic type by using interface in golang

1.泛型起点: interface contains type constraints

在 Go 1.18 版本中,泛型被引入。

在之前的 Go 版本中,interface只是方法的集合,但在 1.18 版本中,为了引入泛型而扩展了原有interface的使用方式,从此interface可以额外表达【类型限制】的语义

interface can contain Type Constraints

2.interface before Go 1.18 without Type Constraints

Go 1.18 前的 interface 是鸭子类型(duck typing)的一种具体实践,实现了 Go 风格的 Duck typing。(注:python大量的鸭子类型,而不需要定义接口。不同语言中鸭子类型的实现不完全相同。golang中使用interface实现鸭子类的方式非常显式和直接)

interface,或者说鸭子类型的关注点在于对象的行为,能做什么;而不是关注对象所属的类型

因此,an interface only defines a set of methods

interface本身就是广义的泛型,是不限制具体实现的泛型

3.interface after Go 1.18 with Type Constraints

为了引入泛型,Go 1.18 后的interface不仅定义行为,还能够限制接口的实现,也就是限制具体实现所属的类型

interface 成为【可以限制具体实现】的泛型,即interface can contain Type Constraints

eg.

type I struct {
    int | int32 | float64  // 限制接口I的实现必须是 int | int32 | float64 的实例对象
}

注意,实际上,接口应当只定制协议,而不应该去限制具体实现。带有 Type Constraints 的 interface 让接口的语义变得模糊不清,将 Type Constraints 纳入 interface 未必是一个好的设计。你见过要限制品牌、材质的充电器的接口协议么?

于是,golang对于带/不带 Type Constraints 的 interface 的使用场景也是有区别的,带有 Type Constraints 的 interface 只能用作泛型的类型限制,保证类型参数的值必须在特定范围内

带有 Type Constraint 的 interface 只能用作泛型中的类型限制。从这种意义上看,interface with Type Constraint 可以认为是新的类型

// You can edit this code!
// Click here and start typing.
// https://go.dev/play/p/4Z84Y-SPFqg
package main

import "fmt"

type IWithTypeConstraint interface {
    ~int32 | ~int64
}

type IWithoutTypeConstraint interface {
}

func main() {
    // var i IWithTypeConstraint = int32(1) // compile failed. cannot use type IWithTypeConstraint outside a type constraint: interface contains type constraints
    // fmt.Println(i)

    var i IWithoutTypeConstraint = int32(1)
    fmt.Println(i)
}

4.泛型的设计

5.泛型的语法

[TypeParameter typeConstraint] eg [T Any]

首先需要定义泛型参数,如 T, 在结构或函数名称后面方括号里面使用。T 可以是任何类型或者接口,即[T]实际上是[T Any]

type Node[T] struct {
    value T
}

T可以加约束条件:
type parameter with constraints

type Node[T comparable] struct {
    value T
}

You can declare your costom type constraint as an interface.

If you declare a type constraint interface with three methods, then use it with a type parameter in a generic function, type arguments used to call the function must have all of those methods.

Constraint interfaces can also refer to specific types

类型限制是泛型的一部分,它允许您限制泛型类型参数可以接受的具体类型。这可以帮助您编写更加安全、可预测的泛型代码。在使用类型限制时,您可以指定一个接口作为限制,泛型类型参数必须满足这个接口。这意味着,泛型类型参数必须实现这个接口所定义的所有方法。

// https://go.dev/play/p/LpSyeLQmhkd

package main

import "fmt"

type Addable interface {
    // define generic type constraints by using interface
    ~int | ~float64
}

func PrintSum[T Addable](a, b T) {
    fmt.Println(a + b)
}

func main() {
    PrintSum(1, 2)     // 输出 3
    PrintSum(1.1, 2.2) // 输出 3.3
}

总结

上一篇 下一篇

猜你喜欢

热点阅读