Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set and protocols in Swift

Tags:

I would like to initialize a Set with values corresponding to the Hashable protocol and a custom protocol.

I tried :

protocol CustomProtocol: Hashable {}  let set = Set<CustomProtocol>() 

But Xcode complains :

Using 'CustomProtocol' as a concrete type conforming to protocol 'Hashable' is not supported

How can I achieve that ?

Thanks in advance.

like image 570
GaétanZ Avatar asked Oct 17 '15 17:10

GaétanZ


People also ask

What is get set in Swift protocol?

Also, it is used to specify whether the property is 'gettable' or 'settable'. Property requirements are declared by 'var' keyword as property variables. {get set} is used to declare gettable and settable properties after their type declaration. Gettable is mentioned by {get} property after their type declaration.

How do protocols work in Swift?

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.

What is gettable and settable in Swift?

Gettable properties are values that you can read. Settable properties are values that you can edit, but not read. If you have a property that's both gettable and settable, you can read and edit the value.


1 Answers

The immediate reason why you can't do what you want to do is that Hashable is a generic protocol. Thus it — or a protocol that derives from it — cannot be used as a Set's element type. A generic type can used only as a constraint in another generic. You will notice that you can't declare a Set<Hashable> either, even though a set's element type must conform to Hashable.

The simplest approach is to make, not a set of protocols, but a set of some object type. For example, if S is a struct that conforms to CustomProtocol (because it conforms to Hashable plus whatever else CustomProtocol entails), you can declare a set of S.

Example:

protocol CustomProtocol: Hashable {  }  func ==(lhs:S,rhs:S) -> Bool {     return lhs.name == rhs.name }  struct S : CustomProtocol {     var name : String     var hashValue : Int { return name.hashValue } }  let set = Set<S>() 

If the problem you're trying to solve is that you want a collection of mixed types which are nevertheless in some way equatable to one another, then that is the very same problem solved by protocol extensions, as explained by the discussion in the Protocol-Oriented WWDC 2015 video.

But it would be simpler just to make all your types classes that derive from NSObject. You can still make them adopt some secondary protocol, of course, but the set won't be defined as a set of that protocol but of NSObject.

like image 71
matt Avatar answered Oct 16 '22 05:10

matt