[swift-evolution] Specify type of a delegate which conforms to a protocol

David Sweeris davesweeris at mac.com
Tue Feb 9 14:56:14 CST 2016


> On Feb 9, 2016, at 12:16, Alex Hoppen <alex at ateamer.de> wrote:
> 
>> On 09 Feb 2016, at 21:00, davesweeris at mac.com wrote:
>> 
>> That might solve Inder’s problem, but strictly speaking it doesn’t actually restrict the type to an enum. This struct meets all of RawRepresentable’s requirements:
>> struct Foo : RawRepresentable {
>>     typealias RawValue = String
>>     init?(rawValue: Foo.RawValue) {
>>         return nil
>>     }
>>     var rawValue: RawValue = "bar"
>> }
>> 
>> (Although in practice I can’t think of why that would matter, since you can’t do anything with a RawRepresentable other than get it’s rawValue or call init?(rawValue: String), and neither of those rely on enum features… I’ll stop being pedantic now.)
> 
> OK, your right, maybe my example was badly chosen. RawRepresentable was the first protocol with an associated type that came into my mind. But the same issue applies for a number of protocols as well, e.g. ArrayLiteralConvertible with associated value Element. Apart from the fact that I don’t like not being able to specify all variable types, you may want to use this in practice to store the values of an Array literal and decide later in what kind of data structure you would like to use to hold the values in the long term.
Your example was not poorly chosen, I was just pointing out that Swift doesn't currently have a mechanism for explicitly restricting a generic type to *only* being an enum, in the way that you can say "T: class" and then T must be a class (which I think is used so that you know T has reference semantics).

>> Anyway, the bigger point is that there’s no way to restrict a generic type to be an enum. I think it’s because there wouldn’t be a way to switch on it (or do other enum-ish things) without knowing all its cases, which requires knowing exactly which type it is, which means it’s no longer a generic type. That’s just a guess, though.
>> 
>> Maybe someone should propose that we allow something like this:
>> func foobar <T, U where T: (case .foo, case .bar)> (value: T) -> U {
>>     switch value {
>>     case .foo: ...
>>     case .bar: ...
>>     }
>> }
> 
> If you specify all the cases your enum should have, you could just specify the enum as well. The list would have to be exhaustive anyway so that the compiler can check that all cases have been covered in a switch statement and I can’t think of any reason why it would be useful to have two enums with exactly the same cases.
Sorry, I was unclear... I meant T would be restricted to any enum that has *at least* a foo case and a bar case... There could be others, too. Speaking of which, there should have been a "default" in there to handle when "value" is one of T's potential other cases.

- Dave Sweeris.

Sent from my iPhone
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160209/7739d365/attachment.html>


More information about the swift-evolution mailing list