这在Go语言中是做什么的,看起来像是一个类型转换。

huangapple go评论92阅读模式
英文:

What is this doing in Go, looks like a cast

问题

x.([]byte) 是 Go 语言中的类型断言语法。它的作用是将接口类型 x 转换为 []byte 类型。

在给定的代码中,x.([]byte) 出现在一个条件语句中。它的作用是检查 x 是否可以转换为 []byte 类型。如果可以,那么条件语句中的代码块会被执行,返回一个 ByteView 结构体,其中的 b 字段被赋值为 bytes。如果不能转换为 []byte 类型,那么条件语句中的代码块不会被执行,继续执行下面的代码,返回一个 ByteView 结构体,其中的 s 字段被赋值为 x.(string)

这段代码的作用是根据输入参数 x 的类型不同,返回不同的 ByteView 结构体。如果 x[]byte 类型,那么返回的 ByteView 结构体的 b 字段为 x;如果 xstring 类型,那么返回的 ByteView 结构体的 s 字段为 x

参考链接:https://github.com/golang/groupcache/blob/master/byteview_test.go#L55

英文:

Can someone explain what the following syntax means in Go, specifially:

x.([]byte)

I am not sure what this means, is this a cast? But for what method since it is just after a dot?

func of(x interface{}) ByteView {
	if bytes, ok := x.([]byte); ok {
		return ByteView{b: bytes}
	}
	return ByteView{s: x.(string)}
}

Reference: https://github.com/golang/groupcache/blob/master/byteview_test.go#L55

答案1

得分: 9

我们将其称为“类型断言”。

这在语言规范中有详细说明。为了在这里提供完整的答案(因为这是完整的答案),而不是只有链接,我将从规范中提取最相关的信息。这是文档,不是我的答案...

对于接口类型的表达式x和类型T,主表达式

x.(T)

断言x不是nil,并且存储在x中的值是类型T。x.(T)的表示法称为类型断言。

更准确地说,如果T不是接口类型,x.(T)断言x的动态类型与类型T相同。在这种情况下,T必须实现x的(接口)类型;否则,类型断言无效,因为x不可能存储类型T的值。如果T是接口类型,x.(T)断言x的动态类型实现接口T。

如果类型断言成立,表达式的值是存储在x中的值,其类型是T。如果类型断言为假,则会发生运行时恐慌。换句话说,尽管x的动态类型只在运行时才知道,但在正确的程序中,x.(T)的类型被认为是T。

var x interface{} = 7  // x的动态类型是int,值为7
i := x.(int)           // i的类型是int,值为7

type I interface { m() }
var y I
s := y.(string)        // 非法:string没有实现I(缺少方法m)
r := y.(io.Reader)     // r的类型是io.Reader,y必须同时实现I和io.Reader

在赋值或初始化的特殊形式中使用的类型断言

v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)

会产生一个额外的无类型布尔值。如果断言成立,ok的值为true。否则,它为false,v的值为类型T的零值。在这种情况下不会发生运行时恐慌。

《Effective Go》是另一个很好的资源,其中还包括有关接口转换和类型断言的部分:
https://golang.org/doc/effective_go.html#interface_conversions

英文:

We refer to this as "type assertion."

This is perfectly documented in the Language Spec. In order to have the whole answer here on SO (since it is the whole answer) and not a link-only answer, I will include it the most relevant information from the spec. This is documentation, not my answer...

> For an expression x of interface type and a type T, the primary
> expression
>
> x.(T)

> asserts that x is not nil and that the value stored in x is of
> type T. The notation x.(T) is called a type assertion.
>
> More precisely, if T is not an interface type, x.(T) asserts that the
> dynamic type of x is identical to the type T. In this case, T must
> implement the (interface) type of x; otherwise the type assertion is
> invalid since it is not possible for x to store a value of type T. If
> T is an interface type, x.(T) asserts that the dynamic type of x
> implements the interface T.
>
> If the type assertion holds, the value of the expression is the value
> stored in x and its type is T. If the type assertion is false, a
> run-time panic occurs. In other words, even though the dynamic type of
> x is known only at run time, the type of x.(T) is known to be T in a
> correct program.
>
> var x interface{} = 7 // x has dynamic type int and value 7
> i := x.(int) // i has type int and value 7
>
> type I interface { m() }
> var y I
> s := y.(string) // illegal: string does not implement I (missing method m)
> r := y.(io.Reader) // r has type io.Reader and y must implement both I and io.Reader

> A type assertion used in an assignment or initialization of the special
> form
>
> v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)
>yields an additional
> untyped boolean value. The value of ok is true if the assertion holds.
> Otherwise it is false and the value of v is the zero value for type T.
> No run-time panic occurs in this case.

Effective Go is another great resource, which also includes a section on Interface conversions and type assertions:
https://golang.org/doc/effective_go.html#interface_conversions

huangapple
  • 本文由 发表于 2016年4月23日 06:44:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/36804423.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定