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

Haravikk swift-evolution at haravikk.me
Mon Oct 10 14:18:01 CDT 2016


> On 10 Oct 2016, at 14:36, Mateusz Malczak <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
> 
> --
> | 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.

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161010/4962d449/attachment.html>


More information about the swift-evolution mailing list