由于Swift Language Guide指出泛型类型可以约束类或协议,如下所示:
public class MyGenericClass<T:Equatable> {
func printEquality(a:T, b:T) {
if a == b {
print("equal")
} else {
print("not equal")
}
}
}
我可以某种方式将T
限制为struct
吗?
我的用例是值类型的观察者类,只能由结构使用。
作为旁注:我知道有例如仅类协议,只能由类实现。这并不是真正相关,但表明有时会有一种特殊的方式来达到目标。
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
// class-only protocol definition goes here
}
答案 0 :(得分:2)
你不能(从Swift 2.2开始)。
根本不可能。 struct
版本没有AnyObject
,即AnyValue
协议(自动为所有值类型实施)。
我自己也遇到过这个问题,我很遗憾地说除了严格遵守非正式协议之外别无他法。希望Swift 3能够解决这个问题。
答案 1 :(得分:1)
另一个答案很好地回答了这个问题(即:你不能(但是?))。
我想我会补充一点,你可以使用运行时内省和可用的初始化器来模拟至少这种行为;这样,只有当T
是一个结构(符合Equatable
)时,通用类的初始化才会成功。
public class MyGenericClass<T: Equatable> {
var foo: T
init?(bar: T) {
foo = bar
if Mirror(reflecting: foo).displayStyle != .Struct {
return nil
}
}
}
struct Foo : Equatable {
let foo = 1
}
func ==(lhs: Foo, rhs: Foo) -> Bool { return lhs.foo == rhs.foo }
/* Example */
if let _ = MyGenericClass<Int>(bar: 1) {
print("Integer")
}
if let _ = MyGenericClass<Foo>(bar: Foo()) {
print("Foo-Struct")
}
// prints only "Foo-Struct"
您可以将失败的初始化解释为您的通用T
与“的不一致”仅允许T
为结构“,并且可能使用可选绑定(/ .. 。)在实践中将它与观察者类一起使用。