Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pointers 如何设计具有可修改字段的结构?_Pointers_Go_Interface - Fatal编程技术网

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

Pointers 如何设计具有可修改字段的结构?,pointers,go,interface,Pointers,Go,Interface,我正在用围棋写一个简单的游戏,有一些问题。我的代码是这样的: 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

我正在用围棋写一个简单的游戏,有一些问题。我的代码是这样的:

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()
}
假设汽车和自行车是非常大的结构,我不想复制。我应该如何设计代码来修改车队中汽车的位置?换句话说,如何设计Fleet struct以修改其可移动对象? 我试着用指向接口的指针进行实验,但我不是个好主意


谢谢你的帮助

问题是您已经用值接收器定义了方法。当您在接收器上调用方法时,接收类型实际上是作为参数传递的,在本例中是通过值传递的,您正在修改该副本

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,直接将传入的值赋值给所述字段,那么不导出字段是没有意义的。此外,我们没有仔细查看,但您正在导出结构上的所有字段,因此您的设置程序是无用的,大多数程序员只需执行
bike.Loc=任何需要的操作,因为此字段是您可能会想到的spublic

您在
Car
bike
上的方法需要指针接收器,不是价值接受者,这不是重点。我在问如何有一个“处理程序”,感谢它,我将能够修改车队中的车辆。Func:AddVehicles将复制它,我无法将其参数类型更改为指针,因为类型是interface。只需将指针传递给
AddVehicles
myFleet.AddVehicles(&myCar);myFleet.AddVehicles和myBike)
;您不必(也不应该)将
vehicles[]Movable
更改为
vehicles[]*Movable
。它可以。。。非常感谢。但是我的心突然爆炸了。如果类型不正确,它如何工作?请参阅:请参阅上面的注释。关于能手和二传手,我同意。他们没有意义,我只是想有接口。也许我应该想出更方便的办法。@mmburr我明白了。我想我会让这个问题保持原样,因为您将使用的解决方案更多的是重构/重新设计,而不是解释为什么您无法修改这些字段。如果你没有真正使用Tim在评论中提出的建议,请大声说出来,我会帮你找到一个可行的解决方案。