我一直在玩Swift,我编码了一个明显的转换结构:
struct MutableAngle {
var degrees : CGFloat
var radians : CGFloat {
return degrees * CGFloat(M_PI) / 180.0
}
init(inRadians : CGFloat) {
degrees = inRadians * 180.0 / CGFloat(M_PI)
}
init(inDegrees : CGFloat) {
degrees = inDegrees
}
}
现在这很好但不优雅,因为它没有对称地对待度和弧度,尽管它确实给出了可变性。这实际上是一个应该被称为度数的结构,它可以提供弧度。例如,我可以写:
var angle : MutableAngle
angle.degrees = 45.0
但不是
var angle : MutableAngle
angle.radians = 0.75
这是最终版本:
struct Angle {
let degrees : CGFloat
let radians : CGFloat
init(inRadians : CGFloat ) {
radians = inRadians
degrees = radians * CGFloat (180 / M_PI)
}
init(inDegrees : Float ) {
degrees = inDegrees
radians = degrees * CGFloat (M_PI / 180)
}
}
使用如下:
var alpha = Angle(inDegrees: 45)
alpha.degrees // returns 45
alpha.radians // returns 0.7853982
// alpha.radians = 0.9 ... is now illegal with let constants
// must use constructor ... provided alpha was defined using 'var'
// i.e. the struct itself is mutable
alpha = Angle(inRadians: 0.9)
alpha.radians // returns 0.7853982
alpha.degrees // returns 45
从var切换到let使它变为可变/不可变取决于alpha的定义方式,我现在不得不使用好的构造函数。所以它的对称性。它还有一个优点,即每次我想使用弧度时都不需要计算。
答案 0 :(得分:0)
这里有两件事:
在Swift中,您不需要为值类型设置单独的可变类型 - 由使用let
或var
实例化该类型的任何人处理。 / p>
您的radians
计算属性只有一个getter - 你可以用setter和getter做你想做的事。
我的实施:
struct Angle {
var degrees : CGFloat = 0
var radians : CGFloat {
get {
return degrees * CGFloat(M_PI) / 180.0
}
set {
degrees = newValue * 180.0 / CGFloat(M_PI)
}
}
init(inRadians : CGFloat) {
radians = inRadians
}
init(inDegrees : CGFloat) {
degrees = inDegrees
}
}
用途:
// immutable
let angle = Angle(inDegrees: 180)
println(angle.radians)
// next line gives an error: can't assign to an immutable instance
angle.radians = angle.radians * 2
// mutable copy
var mutableAngle = angle
mutableAngle.degrees = 10
println(mutableAngle.radians)
// 0.1745...
mutableAngle.radians = CGFloat(M_PI)
println(mutableAngle.degrees)
// 180.0
答案 1 :(得分:0)
一种可能的解决方案是使用enum
及其相关值:
enum MutableAngle {
case Radian(CGFloat)
case Degree(CGFloat)
init(radians:CGFloat) {
self = .Radian(radians)
}
init(degrees:CGFloat) {
self = .Degree(degrees)
}
var radians:CGFloat {
get {
switch self {
case .Radian(let val): return val
case .Degree(let val): return val * CGFloat(M_PI) / 180.0
}
}
set {
self = .Radian(newValue)
}
}
var degrees:CGFloat {
get {
switch self {
case .Degree(let val): return val
case .Radian(let val): return val * 180.0 / CGFloat(M_PI)
}
}
set {
self = .Degree(newValue)
}
}
}
var angle = MutableAngle(radians: 1)
angle.degrees // -> 57.2957795130823
angle.degrees = 180
angle.radians // -> 3.14159265358979