The following code produces a compile error of "Generic parameter "T" cannot be bound to non-@objc protocol type 'AAA' on the fail line. When I use a class instead of a protocol, it works ok. Also, if I add an @objc to the protocol it also works, but only in 6.4 beta. Any suggestions would be helpful.
protocol AAA {
var id: String { get set }
}
class BBB: AAA {
var id: String = ""
}
class BBBService {
func getAll<T:AAA>() -> [T] {
var returnArray:[T] = [T]()
return returnArray
}
}
class TestIt
{
func myTest() {
var service = BBBService()
var fail:[AAA] = service.getAll() // fails with Generic parameter "T" cannot be bound to non-@objc protocol type AAA
var succeed:[BBB] = service.getAll()
}
}
this also fails:
<T where T:AAA>
Update - from a practical perspective, adding the @objc causes other problems in my app. So, that is not an option at this point and time.
The trouble is with this line:
getAll<T: AAA>() -> [T]
you are declaring that T
must be a concrete type that implements the protocol AAA
. It's important to distinguish between the protocol AAA
, ie code like this:
func getAll() -> [AAA] {
var returnArray: [AAA] = [BBB()]
return returnArray
}
which works fine (returns an array of references to AAA
-conforming objects, which could be of type BBB
, or type CCC
), and this:
func getAll<T: AAA>() -> [T] {
var returnArray: [T] = [] // what is T? No idea.
return returnArray
}
in which you are saying to the compiler “write me a version of getAll
, in which T
can be replaced by any specific type that implements AAA
”.
This is why your second version compiles - you're fixing T
to be the actual type BBB
.
Bear in mind, T
might be a struct. In which case the array returned must be sized specifically for whatever struct is being held, right there as a value within the array. As opposed to if the protocol was @objc
in which case it would at least be known to only be a class reference of a fixed size.
If what you actually want is an array of protocols, you should remove the generic placeholder and just return an array of protocols:
func getAll() -> [AAA] {
var returnArray: [AAA] = []
return returnArray
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.