[swift-evolution] [Proposal] Enums with stored properties

Marinus van der Lugt rien at starbase55.com
Mon Oct 10 14:36:46 CDT 2016


> On 10 Oct 2016, at 21:18, Haravikk via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On 10 Oct 2016, at 14:36, Mateusz Malczak <mateusz at malczak.info <mailto:mateusz at malczak.info>> wrote:
>> 
>>> Can't this problem most easily be solved by a raw value? Like so:
>>> 
>>> enum Format : Int {
>>>    case small = 30
>>>    case medium = 60
>>>    case large = 120
>>> 
>>>    var width:Int { return self.rawValue }
>>>    var height:Int { return self.rawValue }
>>> }
>> 
>> This only solves a problem when width/height are the same. Im talking
>> here about more general use case when you can assign different values
>> of different types to an enum case. Please refer to the example code:
>> https://swiftlang.ng.bluemix.net/#/repl/57fb98074f9bcf25fdd415d8 <https://swiftlang.ng.bluemix.net/#/repl/57fb98074f9bcf25fdd415d8>
>> 
>> --
>> | Mateusz Malczak
> 
> I know, but what I'm saying is that this problem could be solved in the multiple values case by allowing tuples as raw values for enums, since that would allow you to specify both width and height. So it'd look something like this:
> 
> enum Format : (width:Int, height:Int) {
>     case small = (30, 30)
>     case medium = (60, 60)
>     case large = (120, 120)
> 
>     var width:Int { return self.rawValue.width }
>     var height:Int { return self.rawValue.height }
> }
> 
> This currently isn't supported as tuples aren't treated as a literal type, even when composed of literal types.
> 

Nice, that ties in well with a recent post here about deriving enums from other types:

struct Size {
   let width: Double
   let height: Double
}

enum Format: Size {
   case small = Size(width: 30, height: 30)
   case medium = Size(width: 60, height: 60)
}

let format = Format.small
let size = format.width

I’d like that a lot!


> Since enum values can be anything that is representable as literal (except arrays, apparently, which I tried but don't seem to work), you can implement this with a lot of boiler-plate like so:
> 
> struct Dimensions : RawRepresentable, ExpressibleByStringLiteral, Equatable {
>     let width:Int, height:Int
>     init(width:Int, height:Int) { self.width = width; self.height = height }
> 
>     init(extendedGraphemeClusterLiteral:String) { self.init(rawValue: extendedGraphemeClusterLiteral)! }
>     init(stringLiteral:String) { self.init(rawValue: stringLiteral)! }
>     init(unicodeScalarLiteral:String) { self.init(rawValue: unicodeScalarLiteral)! }
> 
>     var rawValue:String { return "\(self.width),\(self.height)" }
>     init?(rawValue:String) { let parts = rawValue.components(separatedBy: ","); self.width = Int(parts[0])!; self.height = Int(parts[1])! }
> }
> func == (lhs:Dimensions, rhs:Dimensions) -> Bool { return (lhs.width == rhs.width) && (lhs.height == rhs.height) }
> 
> enum Format : Dimensions {
>     case small = "30,30"
>     case medium = "60,60"
>     case large = "120,120"
> 
>     var width:Int { return self.rawValue.width }
>     var height:Int { return self.rawValue.height }
> }
> 
> Not at all pretty, but it works (and I believe the string parsing should optimise away in practice).
> 
> Anyway, my point is that the best solution to the problem you're trying to solve would be to expand the enum raw value support to include tuples.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161010/3468c3b8/attachment.html>


More information about the swift-evolution mailing list