Я изучаю Голанг, и я родом из PHP. У меня есть немного проблем с пониманием некоторых основных функциональных возможностей.Golang - Почему эта функция меняет входной аргумент?
В частности, прямо сейчас я создаю игру Hearths, и я создал тип CardStack, который имеет некоторые удобные методы, которые можно использовать в стеке карт (читай: рука игрока, сбросить кучу ...), например DrawCards(...)
, AppendCards(...)
...
проблема у меня есть, что функция func (c* CardStack) DrawCards(cards []deck.Card) ([]deck.Card, error) {...}
изменяет аргумент cards []deck.Card
, и я не могу понять, почему и как избежать этого.
Это мой CardStack:
type CardStack struct {
cards []deck.Card
}
Это мой DrawCards
метод:
func (c *CardStack) DrawCards(cards []deck.Card) ([]deck.Card, error) {
return c.getCardsSlice(cards, true)
}
// Returns cards that are missing
func (c *CardStack) getCardsSlice(cards []deck.Card, rm bool) ([]deck.Card, error) {
var err error
var returnc = []deck.Card{}
for _, card := range cards {
fmt.Println("BEFORE c.findCard(cards): ")
deck.PrintCards(cards) // In my example this will print out {Kc, 8d}, which is what I expect it to be
_, err = c.findCard(card, rm) // AFTER THIS LINE THE cards VAR IS CHANGED
fmt.Println("AFTER c.findCard(cards): ")
deck.PrintCards(cards) // In my example this will print out {8d, 8d}, which is not at all what I expected
if err != nil {
return returnc, err
}
}
return returnc, nil
}
// Expects string like "Ts" or "2h" (1. face 2. suit)
func (c *CardStack) findCard(cc deck.Card, rm bool) (deck.Card, error) {
for i, card := range c.GetCards() {
if cc == card {
return c.cardByIndex(i, rm)
}
}
return deck.Card{}, fmt.Errorf("Card not found")
}
func (c *CardStack) cardByIndex(n int, rm bool) (deck.Card, error) {
if n > len(c.GetCards()) {
return deck.Card{}, fmt.Errorf("Index out of bounds")
}
card := c.GetCards()[n]
if rm {
c.SetCards(append(c.GetCards()[:n], c.GetCards()[n+1:]...))
}
return card, nil
}
Чтобы объяснить немного больше - в частности findCard(...)
метод, который вызывается в getCardsSlice
столовых с первоначальным значением (Я добавил комментарии, чтобы указать, где это происходит).
Если это какой-либо помощи, это часть моего main()
метод, который я использую для отладки:
// ...
ss, _ := cards.SubStack(1, 3) // ss now holds {Kc, 8d}
ss.Print() // Prints {Kc, 8d}
cards.Print() // Prints {5c, Kc, 8d} (assigned somewhere up in the code)
cards.DrawCards(ss) // Draws {Kc, 8d} from {5c, Kc, 8d}
cards.Print() // Prints {5c} - as expected
ss.Print() // Prints {8d, 8d} - ???
Что я делаю неправильно и как я должен идти об этом.
Любые виды помощи приветствуются.
Edit:
Весь файл CardStack: http://pastebin.com/LmhryfGc
Edit2:
Я собирался поставить его на GitHub рано или поздно (надеялся после того, как код выглядит полу ОК), вот оно - https://github.com/d1am0nd/hearths-go/tree/cardstack/redo
Мы не можем показать вам конкретную проблему с полным примером, но, похоже, вы проходите несколько кусочков, указывающих на один и тот же массив. Скорее всего, «GetCards» не делает то, что вы думаете. – JimB
Я более чем счастлив обновить вас всем, что вам нужно. Дайте мне минутку, и я отредактирую свое оригинальное сообщение – devk
@JimB Я создал Pastebin со своим стеком карт. 'GetCards' - это просто' return c.cards'. Если есть что-то еще, что вы думаете, может помочь мне сообщить – devk