4

There are some codes below, some gives compile time error some doesn't. Is there a bug or do I miss something about generics here?

1) Doesn't work:

class DataSource: NSObject {
    var dataObjects: [DataType]

    init<T where T: DataType>(dataObjects: [T]) {
        self.dataObjects = dataObjects //Cannot assign value of type [T] to type [DataType]
    }
}

But this works:

class DataSource: NSObject {
    var dataObjects: [DataType]

    init<T where T: DataType>(dataObjects: [T]) {
        self.dataObjects = []
        for dataObject in dataObjects {
            self.dataObjects.append(dataObject)
        }
    }

}

2) Doesn't work:

class DataSource: NSObject {
    var dataObjects: [DataType]

    init<T:DataType>(dataObjects: [T]) {
        self.dataObjects = dataObjects //Cannot assign value of type [T] to type [DataType]
    }
}

But this works:

class DataSource: NSObject {
    var dataObjects: [DataType]

    init<T:DataType>(dataObjects: [T]) {
        self.dataObjects = []
        for dataObject in dataObjects {
            self.dataObjects.append(dataObject)
        }
    }
}

3) This also works:

class DataSource<T: DataType>: NSObject {
    var dataObjects: [T]

    init(dataObjects: [T]) {
        self.dataObjects = dataObjects
    }
}

Also what is the difference between T where T: DataType and T:DataType

P.S.:DataType is an empty protocol

4
  • What is wrong with init(dataObjects: [DataType])? It will still accept an array of anything that conforms to DataType right? Commented Apr 19, 2016 at 13:05
  • Sure. But why don't these work, but others do? Commented Apr 19, 2016 at 13:07
  • You're right, could be a swift bug Commented Apr 19, 2016 at 13:09
  • Take a look at this: stackoverflow.com/questions/36576596/… Commented Apr 19, 2016 at 14:24

1 Answer 1

2

Most likely, the problem is that your protocol is not inheriting from a reference DataType, while the array expects objects.

For example, Any is not always by reference

protocol DataType: Any {
}

class DataSource: NSObject {
    var dataObjects: [DataType]

    init<T:DataType>(dataObjects: [T]) {
        self.dataObjects = dataObjects //Cannot assign value of type [T] to type [DataType]
    }
}

on the other hand, AnyObject always is:

protocol DataType: AnyObject {
}

class DataSource: NSObject {
    var dataObjects: [DataType]

    init<T:DataType>(dataObjects: [T]) {
        self.dataObjects = dataObjects //Works fine
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, if you declare protocol as class protocol like this: protocol DataType: class {}, code will compile.
@osrl I'm not saying it isn't a swift bug. Arrays should be able to contain Any values. But generics are very buggy at the moment, I had a lot of issues with them lately. I am not sure why the 2nd and 3rd work, imho all should work.
Thank you. I was confused about why Any didn't work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.