我做了一个小“ Angle”枚举,以便可以使用不同的可互换角度格式进行编程:
enum Angle { case Radians(CGFloat) case Degrees(CGFloat) case Rotations(CGFloat) }
我发现这种方法有些多余的样板代码。例如,我想添加一个计算的var,它只返回原始底层关联的float:
var raw:CGFloat { switch self { case let .Radians(value): return value case let .Degrees(value): return value case let .Rotations(value): return value } }
我试图将其更改为:
case .Radians(let value), .Degrees(let value): return value
我希望它足够聪明,以至于只能解决一场比赛,所以这场冲突是可忽略的。但是没有这样的设备。编译器说它不能解决两个let value语句之间的冲突。
let value
那么我在Swift枚举中还没有发现一些惯用的聪明之处吗,那么它就可以做到了,这样我就不必在这里重复太多了?
另一个类似的例子是当我实现*函数时:
*
func * (lhs:Angle, rhs:CGFloat) -> Angle { switch lhs { case .Radians: return .Radians(lhs.raw * rhs) case .Degrees: return .Degrees(lhs.raw * rhs) case .Rotations: return .Rotations(lhs.raw * rhs) } }
似乎应该有一种更简单的表达方式:“将相同的枚举类型与我的关联值乘以标量参数”。
(我不确定我在这个问题上是否有很好的头衔,可以随时改善/建议更好)
这是一个有趣的情况:枚举不是某种正确的数据类型,因为该值既不是弧度也不是以度为单位,两者都只是角度而不是真正不同的东西。也typealias Radians = Double没有用,因为没有单元安全。
typealias Radians = Double
也许您可以使用如下所示的方法:
import Darwin struct Angle { enum Unit { case Radians case Degrees case Rotations var radiansFactor : Double { switch self { case Radians: return 1 case Degrees: return 180.0 / M_PI case Rotations: return 1 / 2 / M_PI } } } var unit : Unit { didSet { value /= oldValue.radiansFactor value *= unit.radiansFactor } } var value : Double } func * (var lhs: Angle, rhs: Double) -> Angle { lhs.value *= rhs return lhs } var angle = Angle(unit: .Degrees, value: 180) angle.value // 180.0 angle.unit = .Radians angle.value // 3.141592... angle.unit = .Rotations angle.value // 0.5
哦,关于您的原始问题的答案:不,您不能。