[swift-users] Restricting associated values
David Sweeris
davesweeris at mac.com
Sun Jun 18 22:32:53 CDT 2017
> On Jun 18, 2017, at 19:30, Nevin Brackett-Rozinsky via swift-users <swift-users at swift.org> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170618/2e609a58/attachment.html>
More information about the swift-users
mailing list