Swift协议中的类型约束问题
我有一个协议Swift协议中的类型约束问题,swift,Swift,我有一个协议AProtocol,它有一些数据结构,还有一个协议BProtocol,它有一个动作,使参数符合AProtocol。代码如下所示: protocol AProtocol { // data } protocol BProtocol { func action<T: AProtocol>(completionHandle: (Bool, [T]?) -> ()) } 更新: 我尝试使用类型转换,但调用操作失败,出现另一个错误(“无法转换表达式的类型”
AProtocol
,它有一些数据结构,还有一个协议BProtocol
,它有一个动作,使参数符合AProtocol
。代码如下所示:
protocol AProtocol {
// data
}
protocol BProtocol {
func action<T: AProtocol>(completionHandle: (Bool, [T]?) -> ())
}
更新:
我尝试使用类型转换,但调用操作失败,出现另一个错误(“无法转换表达式的类型”($T4,($T4,($T4,$T5,$T5)->($T4,$T5)->$T3)->($T4,($T4,$T5)->$T3,($T4,$T5)->($T4,$T5)->$T3)->($T4,$T5,$T5)->$T3,$T3)->$T3)->($T3,$T3,$T3,($T4,$T5,$T5,$T5)->$T3,$T3)->$T3,$T3,($T5,$T5)->$T3)->$T3,$T3,$T3)->$T3,$->$T3->$T3'输入“AProtocol'”:
类B类:BProtocol{
var structs=[AStruct]()
函数操作(completionHandle:(Bool[T]?)->()){
completionHandle(true,self.structs.map({$0 as T}))//现在编译错误消失了
}
func testAction(){
action({//Compile error:“无法转换表达式的类型…”
(布尔值,数组结构)在
如果布尔值{
//做点什么
}
})
}
}
我想知道为什么我错了,以及如何解决这个问题。谢谢大家! 你可以用
completionHandle(true, self.structs.map { $0 as T })
我不确定这是一个bug还是语言中的某些限制,禁止您直接强制转换此数组。它可能是不可能的,因为数组是值类型
关于你的最新问题:
您已为操作方法指定了泛型类型,因此编译器无法从上下文获取该类型。您必须显式设置它:
var bClass = BClass()
bClass.action { (boolValue, arrayOfAProtocol: [AProtocol]?) in
if boolValue {
// Do something
}
}
要使其发挥作用,您必须:
- 将结构类型从
更改为[AStruct]
[AProtocol]
- 在
方法中,显式地将action
强制转换为self.structs
[T]
AProtocol
,因此根据方法定义,您应该能够使用它作为泛型类型调用action
。但是BStruct
不是AStruct
(尽管它们实现了相同的协议),因此编译器不知道如何将[AStruct]
转换为[BStruct]
,如果可能的话
根据您试图实现的目标,您可以通过将泛型类型T
从方法级别移动到协议/类级别来稍微更改协议:
protocol BProtocol {
typealias DataType
func action(completionHandle: (Bool, [DataType]?) -> ())
}
class BClass<T: AProtocol>: BProtocol {
typealias DataType = T
var structs = [T]()
func action(completionHandle: (Bool, [T]?) -> ()) {
completionHandle(true, self.structs)
}
}
协议BProtocol{
类型别名数据类型
函数操作(completionHandle:(Bool,[DataType]?)->())
}
B类B类:BProtocol{
typealias数据类型=T
var structs=[T]()
函数操作(completionHandle:(Bool[T]?)->()){
completionHandle(true,self.structs)
}
}
这确保了
structs
包含操作所需的相同类型的元素。谢谢!它确实使编译器平静下来。但是当我尝试调用方法action
时,出现了另一个错误,它似乎与类型转换有关,如我更新的问题所示。仍然有一个小问题:bClass.action{(boolValue,arrayOfAProtocol:[AProtocol]?)
应该是bClass.action{(boolValue,arrayOfAProtocol:[AStruct]?)
非常感谢!事实上,在提问之前,我已经使用了您发布的第二个解决方案。但是,由于我使用了AProtocol
作为接口数据结构,因此我想对类型T
进行限制,以确保所有内容都与AProtocol
通信。因此,我尝试了您的第一个解决方案,并且效果良好很有魅力!如果我能两个都做标记,我会将你的答案标记为已接受。我投赞成票。再次感谢!
var bClass = BClass()
bClass.action { (boolValue, arrayOfAProtocol: [AProtocol]?) in
if boolValue {
// Do something
}
}
class BClass: BProtocol {
var structs = [AProtocol]()
func action<T : AProtocol>(completionHandle: (Bool, [T]?) -> ()) {
completionHandle(true, self.structs as? [T])
}
}
struct BStruct: AProtocol {}
protocol BProtocol {
typealias DataType
func action(completionHandle: (Bool, [DataType]?) -> ())
}
class BClass<T: AProtocol>: BProtocol {
typealias DataType = T
var structs = [T]()
func action(completionHandle: (Bool, [T]?) -> ()) {
completionHandle(true, self.structs)
}
}