首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang -为什么这个函数会改变输入参数?

Golang -为什么这个函数会改变输入参数?
EN

Stack Overflow用户
提问于 2017-01-30 19:48:33
回答 1查看 1.9K关注 0票数 3

我正在学习Golang,我来自PHP背景。有时,我很难理解一些核心功能。

具体来说,现在我正在构建一个壁炉游戏,我已经创建了一个CardStack类型,它可以在一个卡片堆栈中使用一些方便的方法(读:player的手,丢弃的堆.)比如DrawCards(...)AppendCards(...).

,我遇到的问题是,函数func (c* CardStack) DrawCards(cards []deck.Card) ([]deck.Card, error) {...}更改了参数cards []deck.Card,我不知道为什么或者如何避免这一点。

这是我的CardStack:

代码语言:javascript
复制
type CardStack struct {
    cards []deck.Card
}

这是我的DrawCards方法:

代码语言:javascript
复制
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
}

为了解释得更多一些--特别是在getCardsSlice中调用的getCardsSlice方法会与原始值混淆(我已经添加了注释来指示它发生在哪里)。

如果有任何帮助,这是我用于调试的main()方法的一部分:

代码语言:javascript
复制
// ...
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} - ???

我做错了什么,我应该怎么做。

任何帮助都是值得感激的。

编辑

整个CardStack文件:http://pastebin.com/LmhryfGc

Edit2

我迟早会把它放到github上(希望在代码看起来不太好之后),这就是- https://github.com/d1am0nd/hearths-go/tree/cardstack/redo

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-30 20:10:32

在您的示例中,cardsDrawCards中的值是CardsStack.cards片的一个子片,它引用同一个支持数组中的值。

当您调用findCard并从CardStack.cards片中移除卡片时,您正在操作的数组与cards参数使用的数组相同。

当您想要一个切片的副本时,您需要分配一个新的切片并复制每个元素。要在您的示例中这样做,您可以:

代码语言:javascript
复制
ssCopy := make([]deck.Card, len(ss))
copy(ssCopy, ss)
cards.DrawCards(ssCopy)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41944253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档