pointers - 如何设计具有可修改字段的结构?

标签 pointers go interface

我正在用 Go 编写一个简单的游戏,但遇到了一些问题。我的代码如下所示:

package main

import "fmt"

type Location struct {
    X int
    Y int
}

type Car struct {
    MaxSpeed int
    Loc Location
}

func (car Car) SetLocation(loc Location) {
    car.Loc = loc
}

func (car Car) GetLocation() Location {
    return car.Loc
}

type Bike struct {
    GearsNum int
    Loc Location
}

func (bike Bike) SetLocation(loc Location) {
    bike.Loc = loc
}

func (bike Bike) GetLocation() Location {
    return bike.Loc
}
type Movable interface {
    GetLocation() Location
    SetLocation(Location)
}

type Fleet struct {
    vehicles []Movable
}

func (fleet *Fleet) AddVehicles(v ...Movable) {
    for _, x := range(v) {
        fleet.vehicles = append(fleet.vehicles, x) 
    }
}

func (fleet *Fleet) WherTheyAre() {
    for _, v := range(fleet.vehicles) {
        fmt.Println(v.GetLocation())
    }
}

func main() {
    myCar := Car{MaxSpeed: 200, Loc: Location{12, 34}}
    myBike := Bike{GearsNum: 11, Loc: Location{1, 1}}

    myFleet := Fleet{}
    myFleet.AddVehicles(myCar)
    myFleet.AddVehicles(myBike)
    myFleet.WherTheyAre()

    myCar.SetLocation(Location{0,0})
    myFleet.WherTheyAre()
}

假设 Car 和 Bike 是我不想复制的非常大的结构。我应该如何设计代码才能修改作为车队一部分的汽车的位置?换句话说,如何设计 Fleet 结构以能够修改其可移动对象? 我曾尝试使用指向接口(interface)的指针进行试验,但我不是个好主意...

感谢您的帮助!

最佳答案

问题是您已经定义了带有值接收者的方法。当您在接收器上调用方法时,接收类型实际上是作为参数传递的,在这种情况下是按值传递的,并且您正在修改该副本。

func (bike Bike) SetLocation(loc Location) {
    bike.Loc = loc // modifies local copy of Bike
}


func (bike *Bike) SetLocation(loc Location) {
        bike.Loc = loc // modifies the referenced bike
    }

但是你必须以不同的方式声明你的类型,或者使用 & 运算符来调用这些方法,因为你的 main 中有值类型。我倾向于在几乎所有情况下都使用这种语法 bike := &Bike{}。只有当我有一个方便的初始化方法或使用值类型的非常具体的原因(这是非常罕见的)时,我才会放弃它。

但基本上,您不能让 setter 使用值类型接收器。如果你想将这些结构用作值类型,我建议导出字段,这样就可以在没有 getter 或 setter 的情况下访问它们。另外,就样式而言,除非您实际上正在抽象一些逻辑,否则我根本不高兴看到 getter 和 setter 的使用。如果您要提供一个直接将传入的值分配给所述字段的 setter ,那么不导出字段是没有意义的。此外,并没有仔细查看,但您正在导出结构上的所有字段,因此您的 setter 是无用的,大多数程序员只会做 bike.Loc = anythingIWantBecauseThisFieldsExportedWhichYouMayThinkOfAsPublic

关于pointers - 如何设计具有可修改字段的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30792131/

相关文章:

c++ - 调用 COM Release() 函数后指针是否应该设置为空?

pointers - 将接口(interface)实体放入 Google Cloud Datastore 失败

c - 链表上的 map/reduce/filter... map 失败! (在 C 中)

映射并发访问

go - 在 golang 中运行多个条件函数

go - 在go中合并两个结构(相同类型)?

java - Java 类中可以有或不能有内部接口(interface)有充分的理由吗?

c - 重新创建 strstr() 函数

c++ - 通过指针从c++中的函数返回数组,但是程序如何知道数组大小?

c++ - 未定义基类?