首页 > 其他分享 >Golang学习笔记_24——泛型

Golang学习笔记_24——泛型

时间:2025-01-15 21:28:18浏览次数:3  
标签:24 func int tt args Golang want 泛型 string

Golang学习笔记_21——Reader
Golang学习笔记_22——Reader示例
Golang学习笔记_23——error补充


文章目录


泛型

Go语言从1.18版本开始引入了泛型,这是Go语言的一个重要特性,它允许函数、类型和接口在定义时不必绑定到特定的类型上,而是可以在后续使用时再指定具体的类型。这极大地增强了代码的复用性和灵活性。

1. 泛型中的类型参数

类型参数是泛型函数、泛型类型和泛型接口定义中声明的占位符,它们用于表示在泛型实例化时可以指定的具体类型。

1.1 类型参数声明

在泛型定义中,类型参数通过方括号[]中的类型参数列表进行声明。

func Print[T any](x T) {...}
type Pair[T, U any] struct {...}
type Describer[T any] interface {...}
1.2 类型参数的约束

类型参数可以受到约束,这意味着它们必须满足特定的接口。这通过类型约束来实现。

// Generics type constraints
type Number interface {
	int | int64 | float64 // 使用联合类型表示约束
}

func Sum[T Number](nums []T) T {
	var sum T
	for _, num := range nums {
		sum += num
	}
	return sum
}

测试方法

func TestSum(t *testing.T) {

	type args[T Number] struct {
		nums []T
	}
	type testCase[T Number] struct {
		name string
		args args[T]
		want T
	}
	intTests := []testCase[int]{
		{
			name: "int add",
			args: args[int]{
				nums: []int{1, 2, 3},
			},
			want: 6,
		},
	}

	floatTests := []testCase[float64]{
		{
			name: "float add",
			args: args[float64]{
				nums: []float64{1.1, 2.2, 3.3},
			},
			want: 6.6,
		},
	}

	strTests := []testCase[string]{
		{
			name: "string add",
			args: args[string]{
				nums: []string{"1", "2", "3"},
			},
			want: "123",
		},
	}
	for _, tt := range strTests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Sum(tt.args.nums); got != tt.want {
				t.Errorf("Sum() = %v, want %v", got, tt.want)
			}
		})
	}

	for _, tt := range intTests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Sum(tt.args.nums); got != tt.want {
				t.Errorf("Sum() = %v, want %v", got, tt.want)
			}
		})
	}

	for _, tt := range floatTests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Sum(tt.args.nums); got != tt.want {
				t.Errorf("Sum() = %v, want %v", got, tt.want)
			}
		})
	}

}

输出结果

strTests 测试结果
# Golang/generics_demo [Golang/generics_demo.test]
./generics_demo_test.go:37:25: string does not satisfy Number (string missing in int | int64 | float64)
./generics_demo_test.go:40:15: string does not satisfy Number (string missing in int | int64 | float64)
./generics_demo_test.go:48:17: string does not satisfy Number (string missing in int | int64 | float64)

intTests floatTests 测试结果
=== RUN   TestSum
=== RUN   TestSum/int_add
=== RUN   TestSum/float_add
--- PASS: TestSum (0.00s)
    --- PASS: TestSum/int_add (0.00s)
    --- PASS: TestSum/float_add (0.00s)
PASS
1.3 类型参数的实例化

在调用泛型函数、创建泛型类型的实例或赋值给泛型接口时,类型参数会被具体化(实例化)。这可以显式地通过类型参数列表进行,也可以由编译器自动推断。

Print[int](42)           // 显式指定T为int类型
Print(3.14)              // 编译器自动推断T为float64类型
var p Pair[int, string]  // 显式指定T为int,U为string类型

2. 泛型函数

泛型函数允许在函数签名中声明类型参数,这些参数将在函数调用时具体化。

func genericFuncDemo[T any](value T) {
	fmt.Println(value)
}

func testGenericFuncDemo() {
	genericFuncDemo(1)
	genericFuncDemo("hello")
	genericFuncDemo(1.1)
}

测试方法

=== RUN   Test_testGenericFuncDemo
1
hello
1.1
--- PASS: Test_testGenericFuncDemo (0.00s)
PASS

3. 泛型类型

type Pair[T, U any] struct {
	First  T
	Second U
}

func PairDemo() {
	pair := Pair[int, string]{First: 10, Second: "hello"}
	fmt.Println(pair.First, pair.Second)
}

测试方法

func TestPairDemo(t *testing.T) {
	PairDemo()
}

输出结果

=== RUN   TestPairDemo
10 hello
--- PASS: TestPairDemo (0.00s)
PASS

4. 泛型接口

// generics interface
type Describer[T any] interface {
	Describe(T) string
}

type IntDescriber struct {
}

func (num IntDescriber) Describe(i int) string {
	return fmt.Sprintf("类型是:%d", i)
}

func DescribeDemo() {
	var test Describer[int]
	test = IntDescriber{}
	fmt.Println(test.Describe(100))
}

测试方法

func TestDescribeDemo(t *testing.T) {
	DescribeDemo()
}

输出结果

=== RUN   TestDescribeDemo
类型是:100
--- PASS: TestDescribeDemo (0.00s)
PASS

源码

// generics_demo.go 文件
package generics_demo

import "fmt"

// Generics type constraints
type Number interface {
	int | int64 | float64 // 使用联合类型表示约束
}

func Sum[T Number](nums []T) T {
	var sum T
	for _, num := range nums {
		sum += num
	}
	return sum
}

func genericFuncDemo[T any](value T) {
	fmt.Println(value)
}

func testGenericFuncDemo() {
	genericFuncDemo(1)
	genericFuncDemo("hello")
	genericFuncDemo(1.1)
}

type Pair[T, U any] struct {
	First  T
	Second U
}

func PairDemo() {
	pair := Pair[int, string]{First: 10, Second: "hello"}
	fmt.Println(pair.First, pair.Second)
}

// generics interface
type Describer[T any] interface {
	Describe(T) string
}

type IntDescriber struct {
}

func (num IntDescriber) Describe(i int) string {
	return fmt.Sprintf("类型是:%d", i)
}

func DescribeDemo() {
	var test Describer[int]
	test = IntDescriber{}
	fmt.Println(test.Describe(100))
}
// generics_demo_test.go 文件
package generics_demo

import (
	"testing"
)

func TestSum(t *testing.T) {

	type args[T Number] struct {
		nums []T
	}
	type testCase[T Number] struct {
		name string
		args args[T]
		want T
	}
	intTests := []testCase[int]{
		{
			name: "int add",
			args: args[int]{
				nums: []int{1, 2, 3},
			},
			want: 6,
		},
	}

	floatTests := []testCase[float64]{
		{
			name: "float add",
			args: args[float64]{
				nums: []float64{1.1, 2.2, 3.3},
			},
			want: 6.6,
		},
	}

	//strTests := []testCase[string]{
	//	{
	//		name: "string add",
	//		args: args[string]{
	//			nums: []string{"1", "2", "3"},
	//		},
	//		want: "123",
	//	},
	//}
	//for _, tt := range strTests {
	//	t.Run(tt.name, func(t *testing.T) {
	//		if got := Sum(tt.args.nums); got != tt.want {
	//			t.Errorf("Sum() = %v, want %v", got, tt.want)
	//		}
	//	})
	//}

	for _, tt := range intTests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Sum(tt.args.nums); got != tt.want {
				t.Errorf("Sum() = %v, want %v", got, tt.want)
			}
		})
	}

	for _, tt := range floatTests {
		t.Run(tt.name, func(t *testing.T) {
			if got := Sum(tt.args.nums); got != tt.want {
				t.Errorf("Sum() = %v, want %v", got, tt.want)
			}
		})
	}

}

func Test_testGenericFuncDemo(t *testing.T) {
	testGenericFuncDemo()
}

func TestPairDemo(t *testing.T) {
	PairDemo()
}

func TestDescribeDemo(t *testing.T) {
	DescribeDemo()
}

标签:24,func,int,tt,args,Golang,want,泛型,string
From: https://blog.csdn.net/LuckyLay/article/details/145137075

相关文章

  • ABC243
    ABC243E题目大意给出一个无向连通图,在保证任两点最短路\(d(u,v)\)不变的情况下,最多能删多少边。解题思路考虑一条边满足什么条件可以删。给出结论:当\(d(u,v)\lew\)且\(d(u,v)\)所代表的路径不经过\((u,v)\)时,可以删去边\((u,v)\)。证明:当\(d(u,v)\lew\)时,如......
  • 【新教程】Ubuntu 24.04 单节点安装slurm
    背景网上教程老旧,不适用。详细步骤1、安装slurmsudoaptinstallslurm-wlmslurm-wlm-doc-y检查是否安装成功:slurmd--version如果得到slurm-wlm23.11.4,表明安装成功。2、配置slurm。使用命令:sudovi/etc/slurm/slurm.conf在其中输入以下内容:ClusterName=cool......
  • VP Daiwa Securities Co. Ltd. Programming Contest 2024(AtCoder Beginner Contest 38
    A-Humidifier1题意:一个漏水的桶,在零时刻有零升水,进行\(n\)次加水,在\(t_i\)时刻加\(v_i\)升水,每一时刻会漏一生水,问第n次加水后有多少升水。直接模拟即可,每次加水先减去漏掉的水,注意至少有0升,然后加上新加的水。点击查看代码voidsolve(){intn;std::cin>>n;......
  • P3247 [HNOI2016] 最小公倍数 解题报告
    前置知识:可撤销并查集用一个栈记录合并顺序,每次撤销将栈顶的元素恢复但是这种方法不能路径压缩,因为会改变节点之间的关系,为了保证时间,可以按照\(size\)进行合并题意显然为能不能找到一条路径,使这条路径上最大的\(a\)为\(qa\),最大的\(b\)为\(qb\)因为有a和b两个限制,考......
  • 2024,语音 AI 元年;2025,Voice Agent 即将爆发丨年度报告发布
      围绕VoiceAgent产品的研发、商业化和增长的完整生命周期,报告构建出一份VoiceAgent产业生态全景图。 2024年,AI与实时互动技术的结合达到了前所未有的高度。 5月,OpenAI发布了GPT-4o,并展示了其对话功能,仿佛电影《HER》中的智能助手走入了现实生活。 ......
  • 【2024遥感应用组一等奖】基于ENVI Deep Learning的多源SAR影像海带水淹区域提取与分
    作品介绍01应用背景近年来,随着全球气候变化的加剧,海岸带地区面临的洪水威胁日益严重。这些极端天气事件,特别是由热带气旋引发的洪水,不仅给沿海地区带来了巨大的经济损失,还对当地居民的安全和生活产生了深远影响。因此,能够准确识别海岸地区的水淹区域对于防灾减灾、制定应对策......
  • GaussDB 24
    GaussDB介绍华为自主创新研发的分布式关系型数据库。该产品具备企业级复杂事务混合负载能力,同时支持分布式事务,同城跨AZ部署,数据0丢失,支持1000+的扩展能力,PB级海量存储。同时拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定......
  • ABC243做题笔记
    AtcoderBeginnerContest243D-MovesonBinaryTree题目大意有一棵极大的二叉树,有\(2^{10^{100}}-1\)个节点,给定一些操作,输出在线段树上遍历后的最后的节点的编号。解题思路如果直接模拟,显然数据太大,会远超出longlong的范围。有一个条件非常重要:最终的答案在long......
  • ABC 243题解
    ABC243A-C太水不写了。D题意:从完全二叉树上点\(X\)开始移动,每次移动至父节点、左子节点或右子节点。询问N次移动后所处节点,保证答案小于\(10^{18}\)。解法:忘了过程有可能超longlong浪费两分钟。总之就是每一个向父节点操作会消掉最近一个未消掉的向儿子移动操作,然后......
  • (NIPS-2024)GAN 已死;GAN 万岁!现代基线 GAN
    GAN已死;GAN万岁!现代基线GANpaper是布朗大学发表在NIPS2024的工作papertitle:TheGANisdead;longlivetheGAN!AModernBaselineGANCode:https://github.com/brownvc/R3GANAbstract有一种普遍的说法是GAN难以训练,文献中的GAN架构充斥着经验技巧。我......