Reputation: 22763
As the Swift Language Guide points out generic types can be constraint to classes or protocols like this:
public class MyGenericClass<T:Equatable> {
func printEquality(a:T, b:T) {
if a == b {
print("equal")
} else {
print("not equal")
}
}
}
Can I somehow restrict T
to be a struct
?
My use case is an observer class for value types that should only be used by structs.
As a side note: I know that there are e.g. class-only protocols, that are only implementable by classes. This is not really related, but shows that there is sometimes a special way to reach a goal.
protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
// class-only protocol definition goes here
}
Upvotes: 2
Views: 771
Reputation: 18181
You can't (as of Swift 2.2).
It's simply not possible. There's no struct
version of AnyObject
, i.e. an AnyValue
protocol (automatically implemented for all value types).
I've faced this exact problem myself, and I'm sorry to say that there's no solution other than to strictly abide by an informal protocol. Here's to hoping Swift 3 solves this.
Upvotes: 2
Reputation: 73186
The other answer answers this well (i.e.: you can't (yet?)).
I thought I'd add that you can, however, mimic at least the behaviour of this using runtime introspection and failable initializers; such that initialization of your generic class will succeed only if T
is a structure (conforming to 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"
You could interpret failed initialization as non-conformance of your generic T
to "only allow T
to be structures", and possibly use optional binding (/...) to use this with your observer class in practice.
Upvotes: 1