2

I am following this Generic tutorial from Apple https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html.

But in the end of tutorial. I got some problem with this:

var myStack = Stack<String>()
myStack.push("a")
myStack.push("b")
myStack.push("c")

var arrayOfStrings = ["a", "b", "c"]

if allItemsMatch(myStack, arrayOfStrings) {
    print("All items match.")
} else {
    print("Not all items match.")
}

at the line if allItemsMatch(myStack, arrayOfStrings), it says:

Cannot invoke 'allItemsMatch' with an argument list of type '(Stack< String>, [String])'

Here is my code:

import UIKit

struct Stack<Element> {
    var items = [Element]()
    mutating func push(item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}

extension Stack {
    var topItem: Element? {
        return items.isEmpty ? nil : items[items.count - 1]
    }
    mutating func append(item: Element) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
}


func findIndex<T: Equatable>(array: [T], _ valueToFind: T) -> Int? {
    for (index, value) in array.enumerate() {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

let doubleIndex = findIndex([3.14159, 0.1, 0.25], 9.3)
let stringIndex = findIndex(["Mike", "Malcolm", "Andrea"], "Andrea")

protocol Container {
    associatedtype ItemType
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

extension Array: Container {}

func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, _ anotherContainer: C2) -> Bool {
    if someContainer.count != anotherContainer.count {
        return false
    }
    for i in 0..<someContainer.count {
        if someContainer[i] != anotherContainer[i] {
            return false
        }
    }
    return true

}

var myStack = Stack<String>()
myStack.push("a")
myStack.push("b")
myStack.push("c")

var arrayOfStrings = ["a", "b", "c"]

if allItemsMatch(myStack, arrayOfStrings) {
    print("All items match.")
} else {
    print("Not all items match.")
}

Am I missing somewhere?

1 Answer 1

2

You never explicitly conform your Stack<Element> struct to your Container protocol. Therefore Swift's strict type safety will prevent you from passing it into a parameter that expects something that conforms to the Container protocol (even if it implicitly conforms).

You can explicitly conform your Stack to Container via an extension. For example:

extension Stack:Container {}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. But why it still print "Not all items match."
@khuong291 Could it be due to the mistype where you're pushing your strings to stackOfStrings instead of myStack? With that correction, it's working for me.
Ok. Thanks a lot for your help. 😅
@khuong291 Happy to help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.