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)
    }
}