What does asterisk (*struct) notation mean in golang

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

What does asterisk (*struct) notation mean in golang

问题

// NewReaderSize返回一个新的Reader,其缓冲区至少具有指定的大小。如果参数io.Reader已经是具有足够大的大小的Reader,则返回底层Reader。
func NewReaderSize(rd io.Reader, size int) *Reader {
// 它已经是一个Reader了吗?
b, ok := rd.(*Reader)
if ok && len(b.buf) >= size {
return b
}
if size < minReadBufferSize {
size = minReadBufferSize
}
r := new(Reader)
r.reset(make([]byte, size), rd)
return r
}

当我使用os.Open打开一个文件时:

dictFile, err := os.Open(file)

我将把dictFile传递给:

reader := bufio.NewReader(dictFile)

我发现底层代码使用了函数NewReaderSize,但我不理解的是rd.(*Reader)Reader是包bufio中包含的结构体类型。紧随结构体之后的星号是我从中看到的从指针Reader获取值的方式,但它不是一个指针,所以没有意义。而且,它使用了点运算符rd.(*Reader),我完全困惑了。这种用法在第47行是什么意思?这是什么样的符号表示法?

英文:
// NewReaderSize returns a new Reader whose buffer has at least the specified
43	// size. If the argument io.Reader is already a Reader with large enough
44	// size, it returns the underlying Reader.
45	func NewReaderSize(rd io.Reader, size int) *Reader {
46		// Is it already a Reader?
47		b, ok := rd.(*Reader)
48		if ok &amp;&amp; len(b.buf) &gt;= size {
49			return b
50		}
51		if size &lt; minReadBufferSize {
52			size = minReadBufferSize
53		}
54		r := new(Reader)
55		r.reset(make([]byte, size), rd)
56		return r
57	}

When I use os.Open to open a file

dictFile, err := os.Open(file)

I'm going to pass dicFile to

reader := bufio.NewReader(dictFile)

I found the underlying code is using func NewReaderSize, but what I can not understand is rd.(*Reader). Reader is the struct type contained in package bufio. Asterisk followed by a struct is from what I see to get the value from pointer Reader, but it is not a pointer, so it does not make sense. Further more, it's using dot operator rd.(*Reader), I totally got confused. What's the meaning of this kind of usage in line 47? What kind of notation it is?

答案1

得分: 10

你的示例中第47行的语法是类型断言,它断言接口变量的值为特定类型。在你的例子中,语句

b, ok := rd.(*Reader)

断言接口rd的底层值为*Reader类型(指向Reader结构体的指针),将给你一个类型为*Readerb和一个布尔值ok,指示断言是否成功以及底层值是否真的是*Reader类型。

以下是一个抽象的示例(play链接):

type readerA struct {}
func Read(a []byte) (int, error) {}

type readerB struct {}
func Read(a []byte) (int, error) {}

func TakesAReader(r io.Reader) {
   val, ok := r.(*readerA)
   fmt.Println(val, ok)
}

TakesAReader(&amp;readerA{}) // 输出 &amp;{}, true
TakesAReader(&amp;readerB{}) // 输出 nil, false

所以你可以看到,类型断言只是一种提取接口所覆盖的值的方式。

英文:

The syntax in line 47 in your example is a Type Assertion, it asserts the value of interface variables to be of a specific type. Concretely in your case, the statement

b, ok := rd.(*Reader)

asserts the underlying value of the interface rd to be of type *Reader (a pointer to a value of struct Reader), giving you b of type *Reader and a boolean value ok that indicates whether the assertion is OK and the underlying value really is of type *Reader.

An abstract example (play):

type readerA struct {}
func Read(a []byte) (int, error) {}

type readerB struct {}
func Read(a []byte) (int, error) {}

func TakesAReader(r io.Reader) {
   val, ok := r.(*readerA)
   fmt.Println(val, ok)
}

TakesAReader(&amp;readerA{}) // prints &amp;{}, true
TakesAReader(&amp;readerB{}) // prints nil, false

So you see, type assertions are just a way to pull out the value that is covered by an interface.

答案2

得分: 8

newReaderSize接受一个读取器(io.Reader接口)并返回一个指向Reader(在bufio中定义的struct)的指针。

这被称为类型断言:

b, ok := rd.(*Reader)

根据Go语言规范:

对于接口类型的表达式x和类型T,主表达式x.(T) 断言x不是nil,并且存储在x中的值是类型T。表达式x.(T)被称为类型断言。

这行代码将读取器断言为*Reader类型,如果断言成功并且该Reader的缓冲区足够大,它将立即返回(因为它已经是我们想要的类型)。

英文:

newReaderSize takes a reader (io.Reader interface) and returns a pointer to Reader (struct defined in bufio).

This is called a type assertion:

b, ok := rd.(*Reader)

From golang spec:

> 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.

This line is taking that reader and asserting it is a type of *Reader, if it succeeds and that Reader has buffer big enough its immedietly returned (because it's already what we want).

huangapple
  • 本文由 发表于 2014年3月28日 00:13:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/22693275.html
匿名

发表评论

匿名网友

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

确定