从 Swift 中的非泛型函数调用泛型函数
Call generic function from non-generic function in Swift
MMCondition
是在 Swift 中定义的协议,但与 Objective-C 互操作(用 @objc 注释)。
@objc public protocol MMCondition {
static var name: String { get }
static var isMutuallyExclusive: Bool { get }
}
我有以下代码:
// addCondition cannot be generic as I want it to be accessible from Objective-C as well.
public func addCondition(condition: MMCondition) {
// How do I initialize OperationConditionImplementer here?
let operationCondition = OperationConditionImplementer(condition: condition) // doesn't compile
// Error: Cannot invoke initializer for type 'OperationConditionImplementer<T>' with an argument list of type '(condition: MMCondition)'
// Can I use condition.dynamicType to init OperationConditionImplementer somehow?
}
struct OperationConditionImplementer<T: MMCondition> {
let condition: T
static var name: String {
return "Silent<\(T.name)>"
}
static var isMutuallyExclusive: Bool {
return T.isMutuallyExclusive
}
init(condition: T) {
self.condition = condition
}
}
从 Objective-C 开始,您不能使用 documentation 中所述的泛型。
You’ll have access to anything within a class or protocol that’s
marked with the @objc attribute as long as it’s compatible with
Objective-C. This excludes Swift-only features such as those listed
here:
- Generics
...
因此您需要完全删除泛型代码。一种可能的解决方案可能是:
@objc protocol MMCondition {
static var name: String { get }
static var isMutuallyExclusive: Bool { get }
}
struct OperationConditionImplementer {
let condition: MMCondition
var name: String {
return "Silent<\(condition.dynamicType.name)>"
}
var isMutuallyExclusive: Bool {
return condition.dynamicType.isMutuallyExclusive
}
init(condition: MMCondition) {
self.condition = condition
// Here decide comparing types
if condition.dynamicType === ExampleCondition.self {
print(condition.dynamicType.name)
}
}
}
例如,如果您在操场上尝试一下:
class ExampleCondition: NSObject, MMCondition {
static var name: String = "ExampleCondition"
static var isMutuallyExclusive: Bool = false
}
let example = OperationConditionImplementer(condition: ExampleCondition())
您会看到 "ExampleCondition" 打印。
如果你最终切换到纯Swift,你需要在初始化一个OperationConditionImplementer
时指定T
。
您可以将 addCondition
方法定义为:
func addCondition<T: MMCondition>(condition: T) {
let a = OperationConditionImplementer<T>(condition: condition)
}
因为 Swift 通用 类 的 2.0 实例可以实现 Objective-C 协议。我认为不可能有结构实现协议。事实上,我希望您的协议可能需要从 NSObjectProtocol 继承才能在 Objective-C 中使用,这将阻止您使用结构或枚举实现协议。
您还正确地提到您无法从 Objective-C 访问泛型函数。
有关使用泛型实现 Objective-C 协议的具体示例,请查看 this blog post。
MMCondition
是在 Swift 中定义的协议,但与 Objective-C 互操作(用 @objc 注释)。
@objc public protocol MMCondition {
static var name: String { get }
static var isMutuallyExclusive: Bool { get }
}
我有以下代码:
// addCondition cannot be generic as I want it to be accessible from Objective-C as well.
public func addCondition(condition: MMCondition) {
// How do I initialize OperationConditionImplementer here?
let operationCondition = OperationConditionImplementer(condition: condition) // doesn't compile
// Error: Cannot invoke initializer for type 'OperationConditionImplementer<T>' with an argument list of type '(condition: MMCondition)'
// Can I use condition.dynamicType to init OperationConditionImplementer somehow?
}
struct OperationConditionImplementer<T: MMCondition> {
let condition: T
static var name: String {
return "Silent<\(T.name)>"
}
static var isMutuallyExclusive: Bool {
return T.isMutuallyExclusive
}
init(condition: T) {
self.condition = condition
}
}
从 Objective-C 开始,您不能使用 documentation 中所述的泛型。
You’ll have access to anything within a class or protocol that’s marked with the @objc attribute as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:
- Generics
...
因此您需要完全删除泛型代码。一种可能的解决方案可能是:
@objc protocol MMCondition {
static var name: String { get }
static var isMutuallyExclusive: Bool { get }
}
struct OperationConditionImplementer {
let condition: MMCondition
var name: String {
return "Silent<\(condition.dynamicType.name)>"
}
var isMutuallyExclusive: Bool {
return condition.dynamicType.isMutuallyExclusive
}
init(condition: MMCondition) {
self.condition = condition
// Here decide comparing types
if condition.dynamicType === ExampleCondition.self {
print(condition.dynamicType.name)
}
}
}
例如,如果您在操场上尝试一下:
class ExampleCondition: NSObject, MMCondition {
static var name: String = "ExampleCondition"
static var isMutuallyExclusive: Bool = false
}
let example = OperationConditionImplementer(condition: ExampleCondition())
您会看到 "ExampleCondition" 打印。
如果你最终切换到纯Swift,你需要在初始化一个OperationConditionImplementer
时指定T
。
您可以将 addCondition
方法定义为:
func addCondition<T: MMCondition>(condition: T) {
let a = OperationConditionImplementer<T>(condition: condition)
}
因为 Swift 通用 类 的 2.0 实例可以实现 Objective-C 协议。我认为不可能有结构实现协议。事实上,我希望您的协议可能需要从 NSObjectProtocol 继承才能在 Objective-C 中使用,这将阻止您使用结构或枚举实现协议。
您还正确地提到您无法从 Objective-C 访问泛型函数。
有关使用泛型实现 Objective-C 协议的具体示例,请查看 this blog post。