2016-01-04 10 views
0

我很困惑Swift 2.1中的當前數組行爲。我已經閱讀了文檔和許多帖子(可能已經過時),並沒有接近理解。讓陣列行爲在Swift 2.1

這是我的一個撲克牌分成通配符和非通配符代碼:

let wildCards : [Card] = [] 
    let nonWildCards : [NonJoker] = [] 
    Meld.sortAndSeparateWildCards(wildCardRank, cards: self.cards, nonWildCards: nonWildCards, wildCards: wildCards) 

...

static func sortAndSeparateWildCards(wildCardRank : Rank, var cards : [Card], var nonWildCards : [NonJoker], var wildCards : [Card]) { 
    //cards contains the list to be sorted 
    if cards.isEmpty {return} 
    nonWildCards.removeAll() 
    wildCards.removeAll() 
    for card in cards { 
     if (card.isWildCard(wildCardRank)!) {wildCards.append(card)} 
     else {nonWildCards.append(card as! NonJoker)} 
    } 
    cards = nonWildCards.sort(NonJoker.cardComparatorRankFirstDesc) 
    cards += wildCards 
} 

我不明白:

  1. Xcode 堅持我應該將wildCards和nonWildCards更改爲let常量,即使我通過給它們添加值來突變數組(我讀過的很多帖子都說let行爲阻止添加到陣列或從陣列中刪除元素)
  2. 我最初將這些數組作爲inout變量傳遞,因爲我認爲數組是通過價值傳遞的,而不是通過引用傳遞的(文檔表明它們被這樣處理;見本頁底部https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID82

編輯:我以爲代碼工作,但我很困惑。 更正的代碼,根據下面的答案,不正確的行爲isEmpty返回nil。

var wildCards : [Card] = [] 
    var nonWildCards : [NonJoker] = [] 
    Meld.sortAndSeparateWildCards(wildCardRank, cards: &self.cards, nonWildCards: &nonWildCards, wildCards: &wildCards) 

...

static func sortAndSeparateWildCards(wildCardRank : Rank, inout cards : [Card], inout nonWildCards : [NonJoker], inout wildCards : [Card]) { 
    //cards contains the list to be sorted 
    if cards.isEmpty {return} 
    nonWildCards.removeAll() 
    wildCards.removeAll() 
    for card in cards { 
     if (card.isWildCard(wildCardRank)!) {wildCards.append(card)} 
     else {nonWildCards.append(card as! NonJoker)} 
    } 
    cards = nonWildCards.sort(NonJoker.cardComparatorRankFirstDesc) 
    cards += wildCards 
} 

回答

1

數組是Swift中的結構體。按照您所做的方式,所做的更改不會保留在方法之外。如果你想在函數中改變它們,你需要在聲明中將它們標記爲var,並在調用函數時傳遞它們的指針。所以像這樣:

var wildCards = [Card]() 
var nonWildCards = [NonJoker]() 
static func sortAndSeparateWildCards(wildCardRank : Rank, inout cards : [Card], inout nonWildCards : [NonJoker], inout wildCards : [Card]) {} 
Meld.sortAndSeparateWildCards(wildCardRank, cards: &self.cards, nonWildCards: &nonWildCards, wildCards: &wildCards) 
+0

好吧,所以我相應地改變了我的代碼。現在在調用sortAndSeparate self.cards之前有8個值。在sortAndSeparate裏面......調試器將其顯示爲「左值」並且它是空的(所以函數立即返回)。幫幫我! – Opus1217

+0

你確定你傳遞的是具有8個值的相同變量作爲'cards'參數嗎? – cpprulez

+0

是的。我剛剛發現了這個問題:隨着inout變更(上面編輯的代碼),cards.isEmpty返回nil。通過評論這個檢查,一切工作正常。這是否有資格成爲bug? – Opus1217

0

你假設陣列正在按值傳遞,而不是通過引用時是正確的。在Swift中,數組是值類型 - 它們是結構體 - 這意味着如果你想修改它們的內容,你需要聲明它們爲var

現在var具有更廣泛的含義,並且如果它應用於函數參數,它允許您在函數內改變這些參數。但是,請記住,您正在改變作爲參數傳遞的數組副本。

因此,爲了使函數中的數組適用於該函數的調用者可以看到該變量,您需要聲明參數爲inout,該參數通過引用而不是值傳遞給它們。