首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >新的倾斜标志是什么意思?

新的倾斜标志是什么意思?
EN

Stack Overflow用户
提问于 2022-01-28 02:42:11
回答 2查看 3.4K关注 0票数 20

Go介绍了新的令牌~

~T是指具有基础类型T的所有类型的集合

但是,我不明白,请人帮忙解释。

下面是一个例子。

代码语言:javascript
复制
type Ordered interface {
      Integer | Float | ~string
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-28 08:03:48

在Go泛型中,~倾斜标记在表单~T中用于表示底层类型为T的一组类型。

它在泛型提案中也被称为“近似”约束元素,这说明了它在普通语言中的好处:

列出单个类型本身是无用的。为了满足约束,我们希望能够说的不仅仅是int,而是“基础类型为int的任何类型”。..。如果程序使用type MyString string,则程序可以使用具有MyString类型值的<运算符。应该可以用MyString类型实例化一个函数。

如果您想要一个正式的引用,语言规范将底层类型的定义放在它自己的部分中。

每种类型T都有一个基础类型:如果T是预先声明的布尔、数字或字符串类型之一,或者是类型文字,则对应的基础类型是T本身。否则,T的基础类型是类型的基础类型,T在其类型声明中引用该类型。

这包括了非常常见的类型文本和其他带有绑定标识符的复合类型,或者您在预声明标识符上定义的类型,这是泛型建议中提到的情况:

代码语言:javascript
复制
// underlying type = struct literal -> itself -> struct { n int }
type Foo struct {
    n int
}

// underlying type = slice literal -> itself -> []byte
type ByteSlice []byte

// underlying type = predeclared -> itself -> int8
type MyInt8 int8

// underlying type = predeclared -> itself -> string
type MyString string

实际意义是,类型集只有精确元素的接口约束不允许您自己定义的类型:

代码语言:javascript
复制
// hypothetical constraint without approximation elements
type ExactSigned interface {
    int | int8 | int16 | int32 | int64
}

// CANNOT instantiate with MyInt8
func echoExact[T ExactSigned](t T) T { return t }

// constraints.Signed uses approximation elements e.g. ~int8
// CAN instantiate with MyInt8
func echo[T constraints.Signed](t T) T { return t }

与其他约束元素一样,您可以在联合中使用近似元素,比如在constraints.Signed中,也可以在带有或没有语法糖的匿名约束中使用。值得注意的是,只有一个近似元素的语法糖是有效的:

代码语言:javascript
复制
// anonymous constraint
func echoFixedSize[T interface { ~int8 | ~int32 | ~int64 }](t T) T { 
    return t 
}

// anonymous constraint with syntactic sugar
func echoFixedSizeSugar[T ~int8 | ~int32 | ~int64](t T) T { 
    return t 
}

// anonymous constraint with syntactic sugar and one element
func echoFixedSizeSugarOne[T ~int8](t T) T { 
    return t 
}

如前所述,近似元素的一个常见用例是组合类型(切片、结构等)。需要有方法。在这种情况下,必须绑定标识符:

代码语言:javascript
复制
// must bind identifier in order to declare methods
type ByteSeq []byte

func (b ByteSeq) DoSomething() {}

现在,近似元素可以方便地使用ByteSeq进行实例化。

代码语言:javascript
复制
// ByteSeq not allowed, or must convert func argument first
func foobar[T interface { []byte }](t T) { /* ... */ }


// ByteSeq allowed
func bazquux[T interface { ~[]byte }](t T) { /* ... */ }

func main() {
    b := []byte{0x00, 0x01}
    seq := ByteSeq{0x02, 0x03}

    foobar(b)           // ok
    foobar(seq)         // compiler error
    foobar([]byte(seq)) // ok, allows inference
    foobar[[]byte](seq) // ok, explicit instantiation, then can assign seq to argument type []byte

    bazquux(b)          // ok
    bazquux(seq)        // ok
}

注意事项:不能使用类型参数的近似令牌:

代码语言:javascript
复制
// INVALID!
type AnyApprox[T any] interface {
    ~T
}
票数 26
EN

Stack Overflow用户

发布于 2022-01-28 03:02:16

不仅有新的令牌,还有接口的新语法。除了方法约束之外,还可以声明具有类型约束的接口。

要满足接口,类型必须同时满足方法约束和类型约束。

来自文档

表示具有基础类型int的所有类型的接口,该类型实现String方法。 接口{ ~int String() string }

对于具有int“基础类型”的类型,这意味着该类型采用以下形式:

代码语言:javascript
复制
type SomeType int

为了满足方法约束,必须声明具有指定签名的方法:

代码语言:javascript
复制
func (v SomeType) String() string {
  return fmt.Sprintf("%d", v)
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70888240

复制
相关文章

相似问题

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