首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >引用其他类型参数的约束的泛型机制

引用其他类型参数的约束的泛型机制
EN

Stack Overflow用户
提问于 2022-06-16 13:38:12
回答 2查看 147关注 0票数 1

下面是一个通用的split函数,它根据输入大小将一个片分割成几个大小相等的切片(可能最后一个分区除外):

代码语言:javascript
复制
func split[S ~[]T, T any](slc S, size int) []S {
    slices := make([]S, 0, len(slc)/size+1)
    for len(slc) > 0 {
        if size > len(slc) {
            size = len(slc)
        }
        slices = append(slices, slc[:size])
        slc = slc[size:]
    }
    return slices
}

泛型类型参数S的类型为~[]T,其中Tany。这如预期的那样起作用。

需要~来处理定义的类型,例如:

代码语言:javascript
复制
type X []string

如果没有~ in S ~T[]split将无法处理X类型的参数(它仍然适用于[]string)。

还有另一个splitAny函数:

代码语言:javascript
复制
func splitAny[S ~[]any](slc S, size int) []S {
    slices := make([]S, 0, len(slc)/size+1)
    for len(slc) > 0 {
        if size > len(slc) {
            size = len(slc)
        }
        slices = append(slices, slc[:size])
        slc = slc[size:]
    }
    return slices
}

此函数可用于[]interface{}或任何属于type []interface{}的内容。

我的问题是,编译器所采用的生成类型安全代码的机制到底是什么?为什么这两个分裂函数不等价。更广泛地说,为什么splitAny不能与[]string一起工作?

EN

回答 2

Stack Overflow用户

发布于 2022-06-16 14:03:42

dr-约束~[]T引用类型参数,约束~[]any引用静态类型 any

语法S ~[]TS interface { ~[]T }的简写符号,其中约束是匿名接口类型。无论哪种方式,T都引用类型参数的名称,即:

any

  • in作用域约束的
  • 在该类型的参数列表

关键是这里使用any作为约束,所有类型都可以满足这个约束。如果您使用了一个命名的约束,那么它将是一个参数化的接口,如下所示:

代码语言:javascript
复制
type Foo[T any] interface {
    ~[]T
}

然后将函数签名重写为:

代码语言:javascript
复制
func split[S Foo[T], T any](slc S, size int) []S {}

这可能使我们更容易看到~[]T中的~[]T本身就是一个类型参数。就像T在每次实例化时都会有所不同一样,S也是如此。当Tstring时,~[]T~[]string

在另一种情况下,约束~[]any不引用类型参数。any在类型文字[]any中使用静态类型。如果您使用的是命名约束,则如下所示:

代码语言:javascript
复制
// no type parameter needed
type Bar interface {
    ~[]any
    // same as ~[]interface{}
}

然后将函数签名重写为:

代码语言:javascript
复制
func splitAny[S Bar](slc S, size int) []S {}

在后一种情况下,约束不是参数化的,显然只能使用具有基础类型[]any的类型实例化,而不能使用其他任何类型实例化。

您也可以使用[]interface{}实例化它,因为any is a type alias of interface{}.

票数 2
EN

Stack Overflow用户

发布于 2022-06-16 13:45:38

split()中,类型参数T是片的元素类型,因此它接受各种元素类型的切片,如[]string[]int等。

splitAny()中,类型参数S,而不是元素类型,而是片类型本身!这意味着所传递的片的类型可以是[]any,也可以是以它作为其基础类型的类型,但是元素类型必须是any (它是interface{}的别名),而且它不能是其他任何东西,例如不能是string,所以用于S的片类型不能是[]string

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72646826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档