长安链 DApp 开发必学 Go 15:类型参数和泛型类型

27 阅读3分钟

兜兜转转又回来了,一切都是命运石之门的选择吧。

马斯克一有了星际梦,什么跑车豪宅美女都不香了。

当人类知道有珠穆朗玛峰存在的时候,就会去征服它,不会欺骗自己它不存在。

晚清是见过西方的先进科技的,但却自欺欺人的“闭关锁国”,妄图麻痹自己。

后果就是让中华民族走了一段大大的弯路,付出了无数革命鲜血的代价。

所以,每个人都是“西西弗斯”,每个人都有属于他的“巨石”要推。

如果你妄图逃避“巨石”,就会被“巨石”碾压的粉碎。

接受命运的安排吧,不接受,命运之神还是会把你引到“巨石”旁边。

“走啊!少年!去见一见命运里的风!”

中二结束,继续写代码。

我们都知道 Go 是一种静态强类型编程语言,每个变量在声明时都需要规定好它的类型。

想象一个场景,我们需要实现一个函数,它可以传入同一种类型的数据。

这样做的好处是,便于我们写出更通用、更灵活的代码。

举例,一个可以接受 int 型、string 型或者 bool 型等作为参数的函数。

上代码,使用了 Go 中的“类型参数(Type Parameters)”:

package main

import "fmt"

// Index returns the index of x in s, or -1 if not found.
func Index[T comparable](s []T, x T) int {     // 中括号中的就是“类型参数” T
	for i, v := range s {
		// v and x are type T, which has the comparable
		// constraint, so we can use == here.
		if v == x {
			return i
		}
	}
	return -1
}

func main() {
	// Index works on a slice of ints
	si := []int{10, 20, 15, -10}
	fmt.Println(Index(si, 15))  // 在列表中找到整型 15 的索引

	// Index also works on a slice of strings
	ss := []string{"foo", "bar", "baz"}
	fmt.Println(Index(ss, "hello"))  // 在列表中找到字符串型 hello 的索引
}

如代码,Index 函数既可以处理整形,也可以处理字符串型。强大,方便。

通过“类型参数”,可以实现泛型函数,Go 也支持泛型类型。

通过泛型类型,可以方便的实现操作多种数据的数据结构。

上代码:

package main

import “fmt”

// List represents a singly-linked list that holds
// values of any type.
type List[T any] struct {  // 声明一个泛型类型,实现单链表数据结构
	next *List[T]      // 指向下一节点的指针
	val  T             // 本节点包含的数据
}

func main() {
    head := List[int] {next: nil, val: 1}  // 创建头节点
    node := List[int] {next: nil, val: 2}  // 创建下一节点
    
    head.next = &node  // 将下一节点的指针赋值给头节点的 next 变量
    
    // 打印验证
    fmt.Println(head)  
    fmt.Println(node)
    
    head1 := List[string] {next: nil, val: "1"}  // 创建头节点
    node1 := List[string] {next: nil, val: "2"}  // 创建下一节点
    
    head1.next = &node1  // 将下一节点的指针赋值给头节点的 next 变量
    
    // 打印验证
    fmt.Println(head1)  
    fmt.Println(node1)
}

通过泛型类型,实现了同一结构体支持整形或者字符串型。

下章见!!!