我对 Go 很陌生,我已经(从常见问题解答中)读到 Go 既是面向对象又不是面向对象的。我想使用 Structs 创建数据结构,并发现自己试图将 Structs 视为简单的对象。我的典型概念证明是建造一辆汽车。我知道汽车是现实世界的对象,因此它适用于 OOP,这在 Go 中可能很奇怪。但我想 User 类会同样方便,所以这对我来说将是一个有用的学习练习和参考。
此示例编译但无法正常运行。它使用多个源文件,因此您必须操作 GOPATH 并为此创建一个项目文件夹。
它应该如下所示:
$GOPATH/src/car/car.go
$GOPATH/src/car/parts/engine.go
或者另一种看待它的方式:
$ cd /tmp/go/src
$ tree
.
└── car
├── car.go
└── parts
└── engine.go
Main 向下面的 .Start() 请求汽车实例。当它回到主,汽车没有启动。
/* car/car.go */
package main
import (
"car/parts"
"fmt"
)
type Car struct {
sMake string
model string
engine parts.Engine
}
func init() { // optional init of package
// note that we can't use this as a constructor?
}
func main() {
car := Car{
sMake: "AMC",
model: "Gremlin",
}
fmt.Printf("I'm going to work now in my %s %s\n", car.sMake, car.model)
fmt.Println("I guess I should start my car.")
car.Start()
fmt.Println("Engine started?", car.engine.IsStarted())
// fail -- engine started is false :(
}
func (car Car) Start() {
fmt.Println("starting engine ...")
car.engine.Start()
fmt.Println("you'd think it would be started here ...", car.engine)
// but it's not
}
拆分源文件很方便。所有这些都有效
/* car/parts/engine.go */
package parts
import (
"fmt"
)
type Engine struct {
cylinders int
started bool
}
func (engine Engine) Start() {
fmt.Println("Inside the Start() func, started starts off", engine.started)
engine.started = true
fmt.Println("Inside the Start() func, then turns to", engine.started)
// this is a sanity check
}
func (engine Engine) IsStarted() bool {
return engine.started
}
运行此输出:
$ go run car.go
I'm going to work now in my AMC Gremlin I guess I should start my car. starting engine ... Inside the Start() func, started starts off false Inside the Start() func, then turns to true you'd think it would be started here ... {0 true} Engine started? false
在结构上调用函数是有道理的,但我想知道我是否试图以错误的方式操纵内部状态?或者,也许我不了解范围。如果有人可以帮助我解决这个问题,我会非常重视它以供参考。
另外,如果有人对初始化程序有首选或惯用方法。例如,发动机可能默认为 4 个气缸。