有没有一种方法可以在功能指针中快速设置协议的数据类型?
这是我的协议ICRUDOperation
public protocol ICRUDOperation {
associatedtype T
func insert(data:T)
func update(data:T)
func get(data:T) -> [T]
func getList(data: BaseModel) -> [T]
func getPage(data: BaseModel) -> [T]
func delete(data: T)
}
我尝试在其中使用:
func delegate1<W>(sqlite: W, service: W, data: W.T) where W: ICRUDOperation {
sqlite.insert(data: data)
}
var decision = [String : [String:((ICRUDOperation, ICRUDOperation, T) ->())?]]()
func fillDecision() {
decision["Person"]?["1"] = Delegate1
}
我在决策中遇到此错误
Protocol 'ICRUDOperation' can only be used as a generic constraint because it has Self or associated type requirements
fillDecision()
的错误:
Cannot assign value of type '(_, _, _.T) -> ()' to type '((ICRUDOperation, ICRUDOperation, _) -> ())??'
答案 0 :(得分:1)
一旦添加了关联类型,就不再存在“ ICRUDOperation”之类的东西。 PAT(具有关联类型的协议)没有存在形式;它的存在是为了将方法附加到 other 类型,或限制可以将哪些具体类型传递给泛型函数。您不能将PAT存储在变量或字典中或其他任何位置。协议(并且是双倍的PAT)不是抽象类。
要理解的最关键的事情是关联类型是由实现选择的,而不是由调用方选择的。因此,在您的示例中,T
将通过ICRUDOperation的实现进行选择(与Array选择其Collection.Index为Int的方式相同;您不必选择它)。泛型允许调用方选择类型,该类型看起来更像您要实现的目标。
如何解决此问题取决于您的用例,这很难从您的示例中理解。 decision
的目标是什么?
如果您演示预期的ICRUDOperation的两种或三种不同实现,将很有帮助。我不确定“操作的实现”是什么意思。
答案 1 :(得分:0)
我试图了解您如何使用此协议,因此这是我如何使用协议的想法。我不确定这是否能回答您的问题,但也许可以帮助您更接近解决方案。
说我们有一个我们要坚持的模型
struct Item {
var id: Int
var name: String
}
然后我们需要一个可以执行db操作的处理程序
struct ItemDbHandler: ICRUDOperation {
typealias T = Item
func insert(data: Item) {
print("\(#function) \(item)")
}
func update(data: Item) {
print("\(#function) \(item)")
}
func get(data: Item) -> [Item] { //shouldn't this return 1 element
print("\(#function) \(item)")
return []
}
// and so on...
}
并带有一些委托函数
func delegateUpdate<W>(sqlite: W, service: W, data: W.T) where W: ICRUDOperation {
sqlite.update(data: data)
}
我们可以直接使用处理程序,也可以通过函数使用
var item = Item(id: 1, name: "ABC")
var handler = ItemDbHandler()
handler.insert(data: item)
item.name = "abc"
delegateUpdate(sqlite: handler, service: handler, data: item)
在操场上跑步会产生收益
插入(数据:)项(id:1,名称:“ ABC”)
update(data :) Item(id:1,name:“ abc”)
我不知道你想做什么fillDecision
,所以我暂时跳过了。