去 - 修改解引用的结构指针改变大多数结构值,但不改变切片 [英] Go - modify dereferenced struct pointer changes most struct values, but not slices
问题描述
我试图创建一个struct Board(棋盘)的浅拷贝。在保存移动到董事会之前,我需要检查这一举动是否会让移动者进入检查状态。
为此,在Move方法(指针的方法) ,我取消引用指针,更新并检查此 可能的 棋盘。当我更改Board类型的单个值的值(例如 possible.headers =Possible Varient
)时,原始的 b
董事会不变。
但是当我调用updateBoard()方法时,它会更新两个主板。我仍然收到错误(无法移入检查),但主线程认为 b.board
(板子位置)已被更改。
func(b * Board)Move(orig,dest int)error {
//验证
...
/ /更新
可能:= * b //一个浅拷贝?
possible.updateBoard(orig,dest,val,isEmpassant,isCastle)
king:= possible.findKingPositionOfThePlayerWhoMoved()
isCheck:= possible.isInCheck(king)// bool如果isCheck {b $ b return errors.New(无法移入检查)
}
b.updateBoard(orig,dest, val,empassant,isCastle)
return nil
奇怪的是,并非所有的值都被更新 updateBoard()
更改。所以 b.toMove
的值不会改变,但是 b.board
的值不会改变(块的位置)。这意味着如果我传递可能:= b
,游戏只会是白色的移动(toMove在updateBoard()方法中交替出现)。使用可能:= * b
,交替操作直到有人进入检查。然后这个举动被应用于 b.board
,但是错误被抛回并且它仍然是checked-players turn(意思是 possible.updateBoard() $ b
切片不会复制切片的数据,它会创建一个指向原始数组的新切片值。 b
b.board
,a[] byte
,始终指向它的原始值(即使结构持有它是解除引用。abhink的答案使用Gofunc copy(dst,src [] Type)int
, https://golang.org/pkg/builtin/#copy ,一个复制指针值的快捷方式。解决方案 b.board 是一个切片类型,它是一个引用类型( https://blog.golang.org/go-slices-usage-and-internals ),其行为就像一个指针。因此,对possible.board
所做的任何更改都将显示在b
中。您可以尝试复制b.board
,如下所示:
func(b * Board)Move(orig,dest int)error {
//验证
...
//更新
可能:= * b // A'shallow复制'?
boardCopy:= make([] byte,len(b.board))
copy(boardCopy,b.board)
possible.board = boardCopy
possible .updateBoard(orig,dest,val,isEmpassant,isCastle)
// ...
请注意,您必须为所有参考类型执行此类操作。
I'm trying to create a shallow copy of a struct Board (a chessboard). Before saving a move to the board, I need to check if that move puts the mover in check.
To do so, within the Move method (method of a pointer), I dereference the pointer, update and check this possible board for Check. When I change the value of a single value of the Board type (such as
possible.headers = "Possible Varient"
) the originalb
Board is not changed.But here when I call a method updateBoard() it updates both boards. I still receive the error (cannot move into check), but the main thread thinks
b.board
(the board position) has been changed.func (b *Board) Move(orig, dest int) error { // validation ... // Update possible := *b // A 'shallow copy'? possible.updateBoard(orig, dest, val, isEmpassant, isCastle) king := possible.findKingPositionOfThePlayerWhoMoved() isCheck := possible.isInCheck(king) // bool takes the king to check for if isCheck { return errors.New("Cannot move into Check") } b.updateBoard(orig, dest, val, empassant, isCastle) return nil
Strangely, not all the the values updated by
updateBoard()
change. So theb.toMove
value doesn't change, but theb.board
value does (the position of the pieces). This means if I passpossible := b
instead, the game will only ever be white's move (toMove is alternated in the updateBoard() method). Withpossible := *b
, turn alternation works until one moves into check. Then the move is applied tob.board
, but the error is thrown back and it remains the checked-players turn (meaningpossible.updateBoard()
didn't update b.toMove.Edit
As abhink pointed out, in Go Slices usage and internals,
Slicing does not copy the slice's data. It creates a new slice value that points to the original array.
b.board
, a[]byte
, always points to its original value (even when the struct which holds it is dereferenced. abhink's answer uses the Gofunc copy(dst, src []Type) int
, https://golang.org/pkg/builtin/#copy , a shortcut for copying the values of the pointers.解决方案Since
b.board
is a slice type, it is a reference type (https://blog.golang.org/go-slices-usage-and-internals) and behaves like a pointer. So any changes made topossible.board
will show up inb
. You can try making a copy ofb.board
like so:func (b *Board) Move(orig, dest int) error { // validation ... // Update possible := *b // A 'shallow copy'? boardCopy := make([]byte, len(b.board)) copy(boardCopy, b.board) possible.board = boardCopy possible.updateBoard(orig, dest, val, isEmpassant, isCastle) // ...
Note that you'll have to do something like this for all reference types.
这篇关于去 - 修改解引用的结构指针改变大多数结构值,但不改变切片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文