3 回答

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超3個(gè)贊
runtime error: invalid memory address or nil pointer dereference
你肯定知道,這是因?yàn)槟懵暶髁?anio.Reader
但你沒有設(shè)置它的值,所以它仍然等于接口的默認(rèn)值,即nil
.
var testIO io.Reader // ?
傳遞io.Reader
to的Upload
目的是提供要上傳的數(shù)據(jù)。通過傳遞io.Reader
,任意數(shù)據(jù)源可以提供任意數(shù)量的字節(jié),不受內(nèi)存可用性的限制(與 不同[]byte
,它需要在上傳 之前將所有數(shù)據(jù)保存在內(nèi)存中)。io.Reader
通常用于為這種“流式傳輸”操作提供數(shù)據(jù)。
Upload reads from given io.Reader and uploads the file contents
那io.Reader
應(yīng)該是要上傳的數(shù)據(jù)的來源。
io.Reader
可能是來自os.Open()
.
但它可以是任何滿足的東西io.Reader
——例如,它也可以是bytes.Buffer
.
它甚至可能是更深奧的東西,比如對GetObject
來自 AWS 的流行 S3 服務(wù)的 API 調(diào)用的結(jié)果,它也返回一個(gè)io.ReadCloser
which satisfies io.Reader
。
io.Reader
是 Go 接口如何允許獨(dú)立庫相互連接的一個(gè)很好的例子。您使用的 SDK 并不關(guān)心io.Reader
它傳遞了什么;值滿足就足夠了,這是io.Reader
在編譯時(shí)強(qiáng)制執(zhí)行的要求。您可以將任何滿足io.Reader
的東西傳遞給它,并且接口類型保證Upload()
能夠正確處理它。
Upload
需要一個(gè)io.Reader
. 如果你想傳遞類似*os.File
fromos.Open
或io.ReadCloser
from 之類的東西,比如 S3 GetObject,那會起作用,因?yàn)?code>*os.File和io.ReadCloser
滿足 io.Reader
。但是由于Upload
需要io.Reader
,您可以確信它只會調(diào)用io.Reader
. 這意味著你必須在Upload
被調(diào)用后自己關(guān)閉。
確?;〞r(shí)間了解如何io.Reader
讓這個(gè)函數(shù)的輸入保持開放式,同時(shí)還要具體說明它所期望的接口。這是 Go 中最重要的概念之一。

TA貢獻(xiàn)1813條經(jīng)驗(yàn) 獲得超2個(gè)贊
這個(gè):
var testIO io.Reader
相當(dāng)于:
testIO := io.Reader(nil)
所以這就是為什么你對零指針引用感到恐慌的原因:
2021/12/01 18:28:47 http: panic serving 127.0.0.1:61059: runtime error: invalid memory address or nil pointer dereference
goroutine 11 [running]:
io.Reader是一個(gè)允許傳遞通用值的接口,前提是它們實(shí)現(xiàn)了接口(即實(shí)現(xiàn)方法Read)。
由于您正在上傳文件,因此您的字節(jié)流應(yīng)該來自操作系統(tǒng)文件。os.File實(shí)現(xiàn)了正確的Read方法 - 所以是兼容的io.Reader。
所以試試:
f, err := os.Open(uploadFilePath)
if err != nil { /* ... */ }
upload, err := client.Files.Upload(context.TODO(), f, "test", 0)

TA貢獻(xiàn)2037條經(jīng)驗(yàn) 獲得超6個(gè)贊
當(dāng)你定義一個(gè)變量時(shí),它的初始值就是zero value那個(gè)類型的。io.Reader是一個(gè)接口,它的零值是nil。因此 nil pointer dereference error. io.Reader只需在將其傳遞給 Upload 之前對其進(jìn)行初始化:
file, err := os.Open("path/to/file")
// if err != nil { ... }
upload, err := client.Files.Upload(context.TODO(), file, "test", 0)
- 3 回答
- 0 關(guān)注
- 186 瀏覽
添加回答
舉報(bào)