3 回答

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

TA貢獻1813條經驗 獲得超2個贊
這個:
var testIO io.Reader
相當于:
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是一個允許傳遞通用值的接口,前提是它們實現了接口(即實現方法Read)。
由于您正在上傳文件,因此您的字節流應該來自操作系統文件。os.File實現了正確的Read方法 - 所以是兼容的io.Reader。
所以試試:
f, err := os.Open(uploadFilePath)
if err != nil { /* ... */ }
upload, err := client.Files.Upload(context.TODO(), f, "test", 0)

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