我想有一种通用的方法来做像Swift 3这样的事情:
public protocol Callable {
associatedtype In : CVarArg
associatedtype Out : CVarArg
}
public struct IntCallable : Callable {
public typealias In = Int
public typealias Out = Double
public typealias FunctionalBlock = @convention(c) (In) -> Out
public func call(_ block: FunctionalBlock) { /* do stuff */ }
}所以我希望它看起来更像这样:
public protocol Callable {
associatedtype In : CVarArg
associatedtype Out : CVarArg
typealias FunctionalBlock = @convention(c) (In) -> Out
}
public struct IntCallable : Callable {
public typealias In = Int
public typealias Out = Double
}
public extension Callable {
public func call(_ block: FunctionalBlock) { /* do stuff */ }
}但是,我得到了错误:
'(Self.In) -> Self.Out' is not representable in Objective-C, so it cannot be used with '@convention(c)'我是否可以对输入/输出关联类型设置任何约束,允许我声明FunctionalBlock的泛型形式?没有@convention(c),它工作得很好,但是我需要它来形成一个C函数调用。
发布于 2022-03-01 05:34:27
这在Swift中目前是不可能的,因为Swift如何管理作为协议传递的值,而CVarArg是一种协议。
幕后发生的事情是,当在协议的保护伞下传递一个值时,Swift编译器创建一个存在容器来包装该值,这个值在被调用的站点上透明地被打开。
基本上你的街区看起来是这样的:
typealias FunctionalBlock = @convention(c) (Container<In>) -> Container<Out>由于这种幕后转换,您没有传递可以用C表示的值,因此会出现错误。
这与其他与协议相关的问题非常相似,比如著名的Protocol doesn't conform to itself?。
您最好的选择是为所有符合CVarArg的类型添加重载,因为这是一个有限且不可更改的列表。
https://stackoverflow.com/questions/43920260
复制相似问题