> On Jun 18, 2017, at 19:30, Nevin Brackett-Rozinsky via swift-users
> <[email protected]> wrote:
>
> Is there a way to restrict the associated values of an enum? For example,
> suppose I have this type:
>
> enum Angle {
> case radians(Double)
> case degrees(Double)
> }
>
> I want to ensure that the radians values is always in [0, 2π) and the degrees
> values is always in [0, 360). Ideally I would like to write an initializer
> which is called when the user writes eg. “let x: Angle = .degrees(-45)” and
> contains the logic to wrap the provided value into the allowed range (in this
> case by adding a multiple of 360).
>
> I don’t see a way to do it. Is this possible?
>
> The closest I’ve found is to create auxiliary types such as
>
> struct Degree { … }
> struct Radian { … }
>
> and give them appropriate initializers, then use them for the associated
> values. However that is undesirable because it adds an extra level of depth
> to get at the actual numeric values.
>
> Is there a better way?
Not off the top of my head, at least not without changing the syntax.
You could add two inits, with different argument labels, and not directly set
the case: “let x = Angle(degrees: -45)”
You could add "public var radians: Double { get {...} set {...} }" (and again
for "degrees") to `Angle`. The getter would need to switch on self to figure
out if you need to convert between the two (like if someone said
".radians(2).degrees"): “var x = Angle.radians(0); x.degrees = -45"
Alternately, you could add "subscript() -> Double" and switch on self in both
the setter and the getter to figure out if you should be wrapping at 2π or 360
and to do any conversions: “var x: Angle = .radians(0); x[] = -45"
Hope that helps
- Dave Sweeris _______________________________________________
swift-users mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-users