Golang-为什么此函数更改输入参数?

I'm learning Golang and I come from PHP background. I have a bit of trouble understanding some of the core functionalities at times.

Specifically, right now I'm building a Hearths game and I've created a CardStack type, that has some convenient methods one might use in a card stack (read: player's hand, discard pile...) such as DrawCards(...), AppendCards(...)...

The problem I have is that the function func (c* CardStack) DrawCards(cards []deck.Card) ([]deck.Card, error) {...} changes the argument cards []deck.Card and I cannot figure out why or how to avoid this.

This is my CardStack:

type CardStack struct {
    cards []deck.Card
}

This is my DrawCards method:

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
}

To explain a bit more - specifically the findCard(...) method that gets called in getCardsSlice messes with the original value (I've added comments to indicate where it happens).

If it's of any help, this is part of my main() method that I use for debugging:

// ...
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} - ???

What am I doing wrong and how should I go about doing this.

Any kind of help is appreciated.

Edit:

The whole CardStack file: http://pastebin.com/LmhryfGc

Edit2:

I was going to put it on github sooner or later (was hoping after the code looks semi-ok), here it is - https://github.com/d1am0nd/hearths-go/tree/cardstack/redo

In your example, the value of cards in DrawCards is a sub-slice of the CardsStack.cards slice, which is referencing values in the same backing array.

When you call findCard and remove a card from the CardStack.cards slice, you are manipulating the same array that the cards argument is using.

When you want a copy of a slice, you need to allocate a new slice and copy each element. To do this in your example, you could:

ssCopy := make([]deck.Card, len(ss))
copy(ssCopy, ss)
cards.DrawCards(ssCopy)