Go 18.0 专业五


默认标题

<p>go 泛型是什么,用于什么场景,举例</p> <p>&quot;go 泛型&quot; 是指 Golang 语言中新增的泛型特性。它可以让开发者编写更加通用、灵活的代码,从而提高代码的可重用性和可维护性。</p> <p>具体来说,泛型可以在不知道数据类型的情况下编写代码,通过占位符来表示类型,从而实现针对不同数据类型的通用算法或数据结构。这样可以避免重复编写相似的代码,提高代码的效率和可读性。</p> <p>举个例子,在 Go 中实现一个通用的栈(stack)数据结构,就可以使用泛型:</p> <pre><code class="language-go">type Stack[T any] []T func (s *Stack[T]) Push(v T) { *s = append(*s, v) } func (s *Stack[T]) Pop() (T, error) { if s.IsEmpty() { return nil, errors.New(&amp;quot;stack is empty&amp;quot;) } index := len(*s) - 1 res := (*s)[index] *s = (*s)[:index] return res, nil }</code></pre> <p>在这个例子中,<code>[T any]</code> 表示 <code>Stack</code> 类型是一个泛型类型,可以接收任何类型的值。这样,我们就可以创建一个 int 类型的栈、string 类型的栈等等,而不需要针对每种类型都编写一遍栈的代码。</p> <hr /> <p>go泛型的所有使用格式</p> <p>在Go语言中,泛型被称为&quot;类型参数化&quot;。目前(截至2021年9月),Go语言还没有正式的泛型支持,但是Go 1.18版本中将引入泛型支持。下面是Go泛型的使用格式:</p> <p>定义泛型函数或方法: func functionName[T any](arg1 T, arg2 int) {...}</p> <p>func (r *receiverType) methodName[T any](arg1 T, arg2 int) {...}</p> <p>调用泛型函数或方法: functionName(argument1, argument2) variable.methodName(argument1, argument2) 定义泛型类型:</p> <p>在Go语言中,虽然目前还没有正式的泛型支持,但可以使用接口和类型断言来实现类似泛型的功能。下面是一个使用接口和类型断言实现的Max函数,用于返回一个切片中的最大值:</p> <pre><code class="language-go">func Max(slice interface{}, less func(i, j int) bool) interface{} { v := reflect.ValueOf(slice) if v.Kind() != reflect.Slice { panic(&amp;quot;Max: not a slice&amp;quot;) } n := v.Len() if n == 0 { return nil } maxIndex := 0 for i := 1; i &amp;lt; n; i++ { if less(i, maxIndex) { maxIndex = i } } return v.Index(maxIndex).Interface() }</code></pre> <p>这个Max函数接收两个参数:一个切片和一个比较函数less。它首先检查传入的参数是否为一个切片,然后使用反射获取切片的长度和元素。接下来,它遍历切片并使用less函数比较每个元素,找到最大值的索引。最后,它返回最大值。</p> <p>这个Max函数可以用于任何类型的切片,只要在调用时传递正确的类型和比较函数即可。例如,以下代码使用Max函数找到一个int类型切片的最大值:</p> <pre><code class="language-go">slice := []int{3, 5, 2, 8, 1} max := Max(slice, func(i, j int) bool { return slice[i] &amp;lt; slice[j] }) fmt.Println(max) // Output: 8</code></pre> <p>注意,在使用Max函数时,比较函数less必须是一个匿名函数或函数字面量,因为它需要捕获slice变量。</p>

页面列表

ITEM_HTML