// 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 && len(b.buf) >= size {
49 return b
50 }
51 if size < minReadBufferSize {
52 size = minReadBufferSize
53 }
54 r := new(Reader)
55 r.reset(make([]byte, size), rd)
56 return r
57 }
Run Code Online (Sandbox Code Playgroud)
当我使用 os.Open 打开文件时
dictFile, err := os.Open(file)
Run Code Online (Sandbox Code Playgroud)
我要将 dicFile 传递给
reader := bufio.NewReader(dictFile)
Run Code Online (Sandbox Code Playgroud)
我发现底层代码正在使用 func NewReaderSize
,但我无法理解的是rd.(*Reader)
. Reader
是包中包含的结构类型bufio
。星号后跟一个结构体是我看到的从指针中获取值的内容Reader
,但它不是指针,因此没有意义。此外,它使用点运算符rd.(*Reader)
,我完全感到困惑。第47行的这种用法是什么意思?它是一种什么样的符号?
您示例中第 47 行的语法是Type Assertion,它将接口变量的值断言为特定类型。具体来说,在你的情况下,声明
b, ok := rd.(*Reader)
Run Code Online (Sandbox Code Playgroud)
将接口的基础值断言rd
为 type *Reader
(指向 struct 值的指针Reader
),为您b
提供 type*Reader
和一个布尔值ok
,指示断言是否正确以及基础值是否确实是 type *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(&readerA{}) // prints &{}, true
TakesAReader(&readerB{}) // prints nil, false
Run Code Online (Sandbox Code Playgroud)
所以你看,类型断言只是一种提取接口覆盖的值的方法。
newReaderSize
接受一个读取器(io.Reader
接口)并返回一个指向Reader
(struct
在 中定义bufio
)的指针。
这称为类型断言:
b, ok := rd.(*Reader)
Run Code Online (Sandbox Code Playgroud)
从 golang 规范:
对于接口类型和类型 T 的表达式x,主要表达式x.(T)断言 x 不是 nil 并且存储在 x 中的值是类型 T。符号 x.(T) 称为类型断言.
这一行正在接受那个读者并断言它是一种类型*Reader
,如果它成功并且Reader
有足够大的缓冲区,它会立即返回(因为它已经是我们想要的)。
归档时间: |
|
查看次数: |
5234 次 |
最近记录: |