5 泛型
类型参数
s
是满足内置约束comparable
的任何类型T
的切片。x
也是相同类型的值。comparable
是一个有用的约束,它能让我们对任意满足该类型的值使用==
和!=
运算符。
go
func Index[T comparable](s []T, x T) int
go
// Index 返回 x 在 s 中的下标,未找到则返回 -1。
func Index[T comparable](s []T, x T) int {
for i, v := range s {
// v 和 x 的类型为 T,它拥有 comparable 可比较的约束,
// 因此我们可以使用 ==。
if v == x {
return i
}
}
return -1
}
func main() {
// Index 可以在整数切片上使用
si := []int{10, 20, 15, -10}
fmt.Println(Index(si, 15))
// Index 也可以在字符串切片上使用
ss := []string{"foo", "bar", "baz"}
fmt.Println(Index(ss, "hello"))
}
2
-1
练习 泛型类型
作为练习,请为此链表的实现添加一些功能。
- 用全局函数
Add
和Delete
,传递双指针**List[T]
,避免方法接收者语法问题。 - 给
T
加comparable
约束,保证可以用==
。 - 其他方法(如
Find
、Traverse
)仍然用方法接收者*List[T]
,这样intList.Traverse()
能正常调用。 - 无比较使用T any。有比较操作使用T comparabel
go
package main
import "fmt"
// List 表示一个可以保存任何类型的值的单链表。
type List[T any] struct {
next *List[T]
val T
}
// NewList 创建一个新的空链表(返回头指针为 nil)
func NewList[T any]() *List[T] {
return nil
}
// Add 在链表末尾添加一个节点
func Add[T any](l **List[T], value T) {
newNode := &List[T]{val: value}
if *l == nil {
*l = newNode
} else {
current := *l
for current.next != nil {
current = current.next
}
current.next = newNode
}
}
// Delete 删除链表中第一个值等于 value 的节点
func Delete[T comparable](l **List[T], value T) {
if *l == nil {
return
}
if (*l).val == value {
*l = (*l).next
return
}
current := *l
for current.next != nil && current.next.val != value {
current = current.next
}
if current.next != nil {
current.next = current.next.next
}
}
// Find 查找链表中第一个值等于 value 的节点
func Find[T comparable](l *List[T], value T) *List[T] {
current := l
for current != nil {
if current.val == value {
return current
}
current = current.next
}
return nil
}
// Traverse 遍历链表并打印每个节点的值
func Traverse[T any](l *List[T]) {
current := l
for current != nil {
fmt.Print(current.val, " ")
current = current.next
}
fmt.Println()
}
//链表长度
func Len[T any](l *List[T]) int {
current := l
count:=0
for current != nil {
count++
current = current.next
}
return count
}
func Reverse[T any](l *List[T]) *List[T] {
var newHead *List[T] = nil
current := l
for current != nil {
next := current.next
current.next = newHead
newHead = current
current = next
}
return newHead
}
func main() {
// 示例:创建 int 类型链表并操作
var intList *List[int] = NewList[int]()
Add(&intList, 1)
Add(&intList, 2)
Add(&intList, 3)
fmt.Print("链表内容: ")
Traverse(intList) // 输出: 1 2 3
found := Find(intList, 2)
if found != nil {
fmt.Println("找到节点:", found.val)
}
Delete(&intList, 2)
fmt.Print("删除后链表内容: ")
Traverse(intList) // 输出: 1 3
fmt.Printf("链表长度:%v\n",Len(intList))
intList=Reverse(intList)
fmt.Print("翻转链表内容: ")
Traverse(intList) // 输出: 3 1
}