英文:
Modifying struct members through an interface in Go
问题
我在我的Go项目中遇到了一个问题,我想创建一个基类的多个子类,并且能够通过基类/接口变量操作子类的实例(尽管Go中并不存在“类”这个概念)。
为了说明我的意思,这是一个C++的示例代码:
#include
using namespace std;
class Base {
public:
int x,y;
virtual void DoStuff() {};
};
class Thing : public Base {
public:
void DoStuff() { x = 55; y = 99; }
};
Base *gSomething;
int main(int argc, char **argv) {
gSomething = new Thing();
gSomething->DoStuff();
cout << "gSomething = {" << gSomething->x << ", " << gSomething->y << "}" << endl;
return 0;
}
这段代码会输出“gSomething = {55, 99}”。
作为一个对Go不熟悉的人,我希望能够做到类似这样的事情(我觉得这样做相当简洁):
package main
import "fmt"
type IBase interface {
DoStuff()
}
// 基类
type Base struct {
x, y int
}
// 更具体的变体
type Thing struct {
Base
}
func (o Base) DoStuff() {
// 用于满足IBase的存根
}
func (o Thing) DoStuff() {
o.x, o.y = 55, 99
fmt.Println("In Thing.DoStuff, o =", o)
}
var Something IBase
func main() {
Something = new (Thing)
Something.DoStuff()
fmt.Println("Something =", Something)
}
然而,这并不起作用。它可以编译,看起来运行正常,但我没有得到我想要的结果。这是输出结果:
In Thing.DoStuff, o = {{55 99}}
Something = &{{0 0}}
我显然希望最后一行输出为“Something = &{{55 99}}”。
我在设计上完全错了吗(在Go中无法实现这个功能),还是我只是错过了一些细节?
英文:
I've come to a point in a Go project of mine where I'd like to create multiple subclasses of a base class, and be able to operate on instances of the subclasses through a base class/interface variable (I'm using the word "class" even though the concept doesn't really exist in Go).
Here's what it might look like in C++ just to show what I mean:
#include <iostream>
using namespace std;
class Base {
public:
int x,y;
virtual void DoStuff() {};
};
class Thing : public Base {
public:
void DoStuff() { x = 55; y = 99; }
};
Base *gSomething;
int main(int argc, char **argv) {
gSomething = new Thing();
gSomething->DoStuff();
cout << "gSomething = {" << gSomething->x << ", " << gSomething->y << "}" << endl;
return 0;
}
This would print "gSomething = {55, 99}".
Being new to Go I was hoping I could do something like this (which I felt was fairly clean):
package main
import "fmt"
type IBase interface {
DoStuff()
}
// The base "class"
type Base struct {
x, y int
}
// A more specific variant of Base
type Thing struct {
Base
}
func (o Base) DoStuff() {
// Stub to satisfy IBase
}
func (o Thing) DoStuff() {
o.x, o.y = 55, 99
fmt.Println("In Thing.DoStuff, o = ", o)
}
var Something IBase
func main() {
Something = new (Thing)
Something.DoStuff()
fmt.Println("Something = ", Something)
}
Alas, this doesn't work. It compiles, it appears to run properly, but I don't get the result I wanted. Here's the printout:
In Thing.DoStuff, o = {{55 99}}
Something = &{{0 0}}
I was obviously hoping for the last print to say "Something = &{{55 99}}"
Am I completely off on the design here (is this not possible to do in Go), or have I just missed some small detail?
答案1
得分: 5
你的 func (o Thing) DoStuff()
有一个接收者类型为 Thing struct
的接收者,并且在 Go 中结构体是按值传递的。如果你想修改结构体本身(而不是它的副本),你需要通过引用传递它。将这一行改为 func (o *Thing) DoStuff()
,你应该能看到预期的输出。
英文:
Your func (o Thing) DoStuff()
has a receiver of the type Thing struct
and structs are passed by value in Go. If you want to modify the struct (and not a copy of it), you would have to pass it by reference. Change this line to func (o *Thing) DoStuff()
and you should see the expected output.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论