1

I'm currently trying out with some basic data structures like LinkedList. I defined a ListNode class of generics values, like this:

class ListNode<T> {
    var nodeContent: T
    var nextNode: ListNode<T>? = nil
    init() {
    // details omitted here
    }

And then a linked list. I want to implement the contains() method, so I have sth like this:

func contains<T>(_ item: T) -> Bool {
    var currNode = self.head
    while (currNode != nil) {
        if currNode?.nodeContent == item {
            return true
        }
        currNode = currNode?.nextNode
    }
    return false
}

Then it's giving me error saying that '==' cannot applied to T and T types. I then looked through the language guide and changed ListNode class and LinkedList struct to this:

class ListNode<T: Equatable>{}
struct LinkedList<T: Equatable>{}

But it's not working, so I added 'Equatable' to func itself:

func contains<T: Equatable>(_ item: T) -> Bool

Still fails. I tried pasting the sample function from the language guide inside,

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

No error occurs. May I know why it's like this? I tried searching, but all suggested answers like this doesn't clear my doubts. Thanks in advance!

Community
  • 1
  • 1
richards
  • 517
  • 9
  • 27
  • Note that there's no need to constrain `T` to `Equatable` in the actual declaration of `LinkedList` or `ListNode` (a linked list doesn't *have* to have `Equatable` elements) – it would be better to implement an extension `where T : Equatable`, and define your `contains` function there (you could also define a predicate version for unconstrained `T`, just like the stdlib). – Hamish Jan 12 '17 at 10:58
  • Although that being said, it would be better just to conform `LinkedList` to `Sequence` or `Collection`. You'd get all this (plus a lot more) for free. – Hamish Jan 12 '17 at 11:03

1 Answers1

1

You just don't need to make the contains method generic (twice). It's inside of your already generic class and knows about T type. It's right to require T: Equatable in the type declaration.

findIndex(of:in:) works as is, because it's not a method, but rather a standalone generic function.

werediver
  • 4,667
  • 1
  • 29
  • 49
  • Wow, type parameters can shadow each other? Oh my. O.O FWIW: [SR-1420](https://bugs.swift.org/browse/SR-1420). – Raphael Jan 12 '17 at 10:53