2015-12-21 306 views
1

鉴于这种结构:直角三角形实施

struct RightTriangle { 

var length: Double 
var width: Double 

var hypotenuse : Double { 
    get { 
     return sqrt((self.length * self.length) + (self.width * self.width)) 
    } 
    } 
} 

我可以轻松地创建它的一个实例:

var rightTriangleOne = RightTriangle(length: 3.0, width: 4.0) 

,并获得斜边值:

rightTriangleOne.hypotenuse //returns 5.0 

现在,这里的问题

如果我想设置如何将斜边设置为特定值,并让宽度和长度值反映这些变化?

我们可以创建基于新的斜边值,我们重新分配的宽度或长度(在这种情况下宽度)二传手:

set { 
     self.width = sqrt((newValue * newValue) - (length * length)) 
} 

现在,如果我们检查了我们的价值观:

rightTriangleOne.width // 4.0 
rightTriangleOne.length // 3.0 
rightTriangleOne.hypotenuse // 5.0 

一切都很好,但现在让我们尝试将斜边设置为一个新值:

rightTriangleOne.hypotenuse = 10.0 

很酷, š现在检查我们的长度和宽度(宽度应修改本身,让斜边为10,但长度不乱):

rightTriangleOne.width // 9.539392014169456 
rightTriangleOne.length // 3.0 

这是伟大的,所有的,但有一个问题。问题在于,如果我们将长度或宽度设置为除当前值以外的其他任何值,那么斜边会发生改变,而我不希望这样做。

例如

如果我设置斜边10,并且宽度为4,长度应该设置为9.16左右。

此实现是否可行?我试图严格执行计算属性。

在此先感谢。在widthlength

+0

我不知道swift,但总的来说,你需要一个斜边长度不变的专用类型,或者一个专门的例程,它可以在保持ac的同时改变长度或宽度即时斜边长度。 – phoog

+0

是的,我在想同样的事情。我有一位同事向我提出了这个建议,而且我只是通过计算属性来解决这个问题。寄予厚望,我会继续发布问题。感谢您的帮助@phoog –

+0

因此,如果您设置了任何两个属性,第三个属性会自动计算? – vacawama

回答

0

使用自定义setter方法:

struct RightTriangle: CustomStringConvertible { 
    private var _length: Double 
    private var _width: Double 

    var length: Double { 
     get { 
      return _length 
     } 
     set { 
      let h = self.hypotenuse 
      _length = newValue 
      _width = sqrt(h * h - _length * _length) 
     } 
    } 

    var width: Double { 
     get { 
      return _width 
     } 
     set { 
      let h = self.hypotenuse 
      _width = newValue 
      _length = sqrt(h * h - _width * _width) 
     } 

    } 

    var hypotenuse: Double { 
     get { 
      return sqrt(length * length + width * width) 
     } 
     set { 
      _width = sqrt((newValue * newValue) - (length * length)) 
     } 
    } 

    init(length: Double, width: Double) { 
     _length = length 
     _width = width 
    } 

    var description: String { 
     return "length = \(length), width = \(width), hypotenuse = \(hypotenuse)" 
    } 
} 

var x = RightTriangle(length: 3, width: 4) 
x.hypotenuse = 10 
x.width = 4 

print(x) // length = 9.1651, width = 4.0, hypotenuse = 10.0 

实例变量_length_width什么实际存储的三角形的尺寸。他们相应的属性有自定义setter来协调变化到另一边。

这种带有2个假设:

  • 如果更改hypotenuse,这是width将被改变,以匹配
  • 它有一个不可能三角尺寸没有错误检查,如阴性,或length = 10, hypotenuse = 5然后width = nan
+0

体面的想法,但你不需要单独的私有存储属性 - 只需使用'willSet'或'didSet'。 – rickster