英文:
Runtime error: When accessing a Reader in struct
问题
我是你的中文翻译助手,以下是你要翻译的内容:
我刚开始学习Go语言,尝试实现一个用于视频操作(下载、上传、转码)的接口。在我的下载方法中,我创建了一个Reader并将其赋值给结构体变量'fileContent'。然后我想在我的上传方法中访问这个Reader,但是它抛出了一个运行时错误。
panic: runtime error: invalid memory address or nil pointer dereference
以下是我在Go Playground中的代码链接。任何帮助都将非常感谢。
https://play.golang.org/p/ib38IQ6AZI
英文:
I'm new to go and trying to implement an interface for video operations (download, upload, transcode). In my download method I'm creating a Reader and assigning it to struct variable 'fileContent'. I'd then like to access the Reader in my upload method but it's throwing a runtime error.
> panic: runtime error: invalid memory address or nil pointer dereference
Below is a link to my code in go playground. Any help would be great.
答案1
得分: 3
问题在于你使用了非指针接收器:
func (b BaseVideo) Download() (err error) {
b.fileContent = bytes.NewReader([]byte("abc"))
return nil
}
这意味着你调用 Download()
方法时,它会得到一个 BaseVideo
值的副本。你在方法内修改了这个副本(将一个新的 Reader
赋值给 fileContent
字段),但原始的 BaseVideo
不会被修改。
解决方法是使用指针接收器:
func (b *BaseVideo) Download() (err error) {
b.fileContent = bytes.NewReader([]byte("abc"))
return nil
}
当然,如果你将接收器修改为指针,类型 BaseVideo
将不再实现 Video
接口,只有指向 BaseVideo
的指针才会实现该接口,因此还需要修改 NewBaseVideo
,使其返回指向结构体值的指针:*BaseVideo
。你可以通过取结构体字面量的地址来实现这一点:
func NewBaseVideo(path, name string) Video {
return &BaseVideo{
Path: path,
Name: name,
}
}
英文:
The problem is that you're using non-pointer receiver:
func (b BaseVideo) Download() (err error) {
b.fileContent = bytes.NewReader([]byte("abc"))
return nil
}
This means your Download()
method gets a copy of the BaseVideo
value you're calling it on. You modify this copy inside the method (you assign a new Reader
to the fileContent
field), but the original BaseVideo
will not be modified.
Solution: use a pointer receiver:
func (b *BaseVideo) Download() (err error) {
b.fileContent = bytes.NewReader([]byte("abc"))
return nil
}
Of course if you modify the receiver to be a pointer, the type BaseVideo
will no longer implement the Video
interface, only a pointer to BaseVideo
, so also modify NewBaseVideo
to return a pointer to the struct value: *BaseVideo
. You can achieve this by taking the address of the struct literal:
func NewBaseVideo(path, name string) Video {
return &BaseVideo{
Path: path,
Name: name,
}
}
答案2
得分: 2
如果你想在方法中改变值,方法的接收者应该是一个指针。将
func (b BaseVideo) Download() (err error)
替换为
func (b *BaseVideo) Download() (err error)
在playground上的可工作代码:https://play.golang.org/p/hZ8-RwzVYh。
英文:
If you want to mutate the value in a methods, the receiver of the method should be a pointer. Replace
func (b BaseVideo) Download() (err error)
and such with
func (b *BaseVideo) Download() (err error)
Working code on the playground: https://play.golang.org/p/hZ8-RwzVYh.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论