So, playing with Swift, I ran into this problem, and it scared me.
I have a class Card:
class Card { var contents = "" var chosen = false var matched = false var description: String { get { return self.contents } } func match(otherCards: Card[]) -> Int {...} }
and the PlayingCard class, which subclasses the Card:
class PlayingCard: Card { var suit: Suit var rank: Rank override var contents: String { get { return "\(rank.description())\(suit.toRaw())" } set { } } init(rank: Rank, suit: Suit) { self.suit = suit self.rank = rank super.init() } override func match(otherCards: Card[]) -> Int {...} }
As you can see, in Card, the description property is computed from the contents property. However, when I create an instance of PlayingCard, I have a computed contents property that overrides the stored contents property for the Map. However, if I call my PlayingCard description , it returns the saved contents card, not the PlayingCard, the actual contents .
func testPlayingCardProperties() { var card = PlayingCard(rank: .Ace, suit: .Spades) XCTAssert(card.contents == "A♠️", "Contents not overriden.") // TRUE XCTAssert(card.description == "A♠️", "Description not overriden.") // FALSE?? }
What's happening? note that
func testCardProperties() { var card = Card() card.contents = "Test Card" XCTAssert(card.contents == "Test Card", "Contents getter error.") // TRUE XCTAssert(card.description == "Test Card", "Description getter error.") // TRUE }
works as expected.
UPDATE
I ran the following on Playground ... and it worked. Still no luck outside of him.
class Card { var contents = "" var chosen = false var matched = false var description: String { get { return contents } } func match(otherCards: Card[]) -> Int { var score = 0 for card in otherCards { if card.contents == contents { score += 1 } } return score } } enum Suit: String { case Diamonds = "♦️" case Hearts = "♥️" case Spades = "♠️" case Clubs = "♣️" static func allSuits() -> Suit[] { return [.Diamonds, .Hearts, .Spades, .Clubs] } } enum Rank: Int { case Ace = 1 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King func description() -> String { switch self { case .Ace: return "A" case .Jack: return "J" case .Queen: return "Q" case .King: return "K" default: return String(toRaw()) } } } class PlayingCard: Card { var suit: Suit var rank: Rank override var contents: String { get { return "\(rank.description())\(suit.toRaw())" } set { } } let maxRank = 13 init(rank: Rank, suit: Suit) { self.suit = suit self.rank = rank } override func match(otherCards: Card[]) -> Int { let allCards = otherCards + [self] let testMatches = { () -> (Card, Card[])[] in var result: (Card, Card[])[] = [] for i in 0..allCards.count { result += (allCards[i], Array(allCards[0..i] + allCards[(i + 1)..allCards.count])) } return result }() let scores = testMatches.map({ (card, otherCards) -> Int in if let playingCard = card as? PlayingCard { var rankValue = 1.0 var suitValue = 1.0 for matchCard in otherCards { if let matchPlayingCard = matchCard as? PlayingCard { if (matchPlayingCard.rank == playingCard.rank) { rankValue *= 8; } else { rankValue /= 2; } if (matchPlayingCard.suit == playingCard.suit) { suitValue *= 2; } else { suitValue /= 2; } } } if rankValue >= 1.0 { return Int(rankValue) } else if suitValue >= 1.0 { return Int(suitValue) } else { return 0 } } else { return 0 } }) return scores.reduce(Int.min, combine: { $0 > $1 ? $0 : $1 }); } } var card = PlayingCard(rank: .Jack, suit: .Spades) card.description
Could this be an Xcode bug?