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 关注
- 139 浏览
添加回答
举报