以下代码产生编译错误“通用参数”T“无法绑定到失败行上的非@objc协议类型'AAA'。当我使用类而不是协议时,它可以正常工作。 ,如果我将@objc添加到协议中它也可以,但只能在6.4 beta。任何建议都会有所帮助。
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()
}
}
这也失败了:
<T where T:AAA>
更新 - 从实际角度来看,添加@objc会导致我的应用中出现其他问题。所以,在这个时间点,这不是一个选择。
答案 0 :(得分:0)
麻烦在于这一行:
getAll<T: AAA>() -> [T]
您声明T
必须是实现协议AAA
的具体类型。区分协议AAA
很重要,即代码如下:
func getAll() -> [AAA] {
var returnArray: [AAA] = [BBB()]
return returnArray
}
工作正常(返回对AAA
的引用数组 - 符合对象,可以是BBB
类型,或类型CCC
),并且:
func getAll<T: AAA>() -> [T] {
var returnArray: [T] = [] // what is T? No idea.
return returnArray
}
您要对编译器说“给我写一个getAll
版本,其中T
可以替换为实现AAA
的任何特定类型。”
这就是您的第二个版本编译的原因 - 您将T
修改为实际类型BBB
。
请记住,T
可能是一个结构。在这种情况下,返回的数组必须专门针对所持有的任何结构进行大小调整,并将其作为数组中的值。相反,如果协议是@objc
,在这种情况下,至少只知道它是固定大小的类引用。
如果您真正想要的是一组协议,则应删除通用占位符并返回一组协议:
func getAll() -> [AAA] {
var returnArray: [AAA] = []
return returnArray
}