2014-03-27 94 views
3
// 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 } 

意味着當我使用os.Open打開文件是什麼星號(*結構)符號在golang

dictFile, err := os.Open(file) 

我要去dicFile傳遞給

reader := bufio.NewReader(dictFile) 

我發現底層代碼使用func NewReaderSize,但我不明白的是rd.(*Reader)Reader是包bufio中包含的結構類型。星號跟着一個結構是從我看到的從指針Reader得到的值,但它不是一個指針,所以它沒有任何意義。此外,它使用點運算符rd.(*Reader),我完全糊塗了。第47行中這種用法的含義是什麼?它是什麼樣的符號?

回答

3

newReaderSize需要讀取器(io.Reader接口),並返回一個指針,指向Reader(在bufio定義struct)。

這被稱爲類型的斷言:

b, ok := rd.(*Reader) 

從golang規格:

當x接口類型和類型T的表達式,主 表達X(T)聲明x不爲零,並且x中存儲的值 的類型爲T.註釋x。(T)稱爲類型斷言。

該行正在採取的是讀者和斷言它是一種類型的*Reader,如果成功,並且Reader有足夠的緩衝其immedietly返回(因爲它已經我們想要的)大。

3

您示例中第47行的語法爲Type Assertion,它將接口變量的值聲明爲特定類型的值。具體你的情況,聲明

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(&readerA{}) // prints &{}, true 
TakesAReader(&readerB{}) // prints nil, false 

所以你看,斷言類型僅僅是退出由一個接口所覆蓋的值的方式。