go tour泛型

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
}
相关推荐
Helix250几秒前
Windows安装方式演变史:从软盘到USB启动盘的完整迭代指南
windows·系统安装·系统重装·启动盘制作·mct工具·电脑装机·uefi安装
维克兜率天8 分钟前
【维克】统计套利建模:从因子到信号的完整流程
android·开发语言·python·算法·kotlin
Pin_Qing13 分钟前
同一天,谷歌半价卖旗舰,阶跃翻倍收缓存
大数据·开发语言·人工智能·程序人生·缓存
2501_9307077819 分钟前
使用C#代码在 Word 文档中添加、插入或删除页面
开发语言·c#·word
没有梦想的咸鱼185-1037-166322 分钟前
从通量数据到SCI论文——AI-R语言生态系统碳水热通量及其机制分析与论文
开发语言·人工智能·数据分析·r语言
weixin_4617694028 分钟前
conda create 创建容器 Failed to resolve ‘repo.anaconda.com‘问题
开发语言·python·conda·repo·网络问题·无法创建
Want59530 分钟前
Python生日蛋糕
开发语言·python
C语言小火车35 分钟前
C++ 为什么越来越依赖标准库?
java·开发语言·c++
FOAF-lambda39 分钟前
winuia-auto 截图全攻略(ToBitmap、Screenshot 与 CaptureToImage 详解)
windows·python·自动化
郝学胜-神的一滴43 分钟前
金融数据分析实战:从数据清洗到策略回测,Python全链路落地
开发语言·python·程序人生·金融·数据挖掘·数据分析