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

Mateusz Malczak mateusz at malczak.info
Mon Oct 10 14:34:44 CDT 2016


> 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:

We have three different possible solution
1. stored properties defined as part of enumeration type
enum RectSizes: MyRect
{
    let height:Int
    let width:Int
    case Small(width: 30, height: 30)
    case Medium(width: 60, height: 60)
    case Large(width: 120, height: 120)
}

2. struct as rawValue
struct MyRect
{
    var height:Int
    var width:Int
    var area:Int {return height:Int*width}
}

enum RectSizes: MyRect
{
    case Small(30,30)
    case Medium(60,60)
    case Large(120,120)
}

3. tuples as rawValue
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 }
}

Solutions 2 and 3 are quire similar, to get value of a stored property
we need to use rawValue or define value getters. In addition in
solution 2 we define an additional data type just to be used as an
enumeration type rawValue type. In my opinion, first approach would be
a best solution, type definition is clear and self-explanatory because
it is similar to how enums/classes are defined.


--
| Mateusz Malczak
+-------------------------------


2016-10-10 21:18 GMT+02:00 Haravikk <swift-evolution at haravikk.me>:
>
> 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.


More information about the swift-evolution mailing list