如果在swift中简化嵌套

时间:2015-10-26 08:43:11

标签: swift

我的应用程序有一个名为MyDevice的类,用于与硬件通信。这个硬件是可选的,实例变量也是如此:

var theDevice:MyDevice = nil

然后,在应用程序中,我必须初始化设备(用于通信),然后执行自检以检查其可用性和执行准备情况。如果此操作失败,则设备不可用/无法访问/出现故障。

这是我过于复杂的代码。我正在寻找如何简化它。

if let device = self.theDevice
{
    device.initDevice()

    if (!device.selfTest())
    {
        self.theDevice = nil;
    }
}

我尝试将所有测试与&&组合在if语句中,但它失败了。 问题是我在函数开头有12个用于各种设备。它需要很大的空间而且很脏。如何在Swift中组合这些语句?

3 个答案:

答案 0 :(得分:0)

您可以使用?可选链接,并合并if case let模式匹配和where语句

theDevice?.initDevice()
if case let selfTest? = theDevice?.selfTest() where !selfTest{
    theDevice = nil
}

但我希望if let可选展开以提高可读性。

答案 1 :(得分:0)

您可以通过initDevice返回self来改善这一点,然后您可以执行以下操作:

if case let selfTest? = theDevice?.initDevice().selfTest() where !selfTest {
    theDevice = nil
}

另一种选择可能是让initDevice执行selfTest并将其返回。

所有这一切都假定initDevice是您的代码,或者您可以采用某种方式进行编辑。

如果它不可编辑,您可以随时进行扩展,并在其中创建一个新方法:

extension TheDeviceClass {

    func initAndTest() -> Bool {
        initDevice()
        return selfTest()
    }
}

然后使用以下内容调用它:

if case let selfTest? = theDevice?.initAndTest() where !selfTest {
    theDevice = nil
}

但这可能会使它比你想要的更复杂。如果您经常使用此代码,请考虑将其放在另一种方法中。

答案 2 :(得分:0)

我认为您应该通过定义可用的初始化程序来更改MyDevice实现以减少冗余,并在其中执行所有检查。因此,如果初始化失败,您将得到一个nil并且可以将它分配给另一个类的相关属性,甚至不需要检查12个设备的方法。

class MyDevice {
  func selfTest() -> Bool {
    // test
    return testresult
  }

  func initDevice() {
    // initialization
  }

  init?() {
    self.initDevice()
    if !self.selfTest() {
      return nil
    }
  }
}

如果你不想过多地改变你的代码,你可能只需定义一个闭包来减少这些冗余代码,就像这样(它仍然看起来很难看,所以我不建议你这样做。):

class SomeClassThatHasTwelveDevices {
  var theDeviceOne: MyDevice?
  var theDeviceTwo: MyDevice?
  var theDeviceThree: MyDevice?
  var theDeviceFour: MyDevice?
  var theDeviceFive: MyDevice?
  var theDeviceSix: MyDevice?
  var theDeviceSeven: MyDevice?
  var theDeviceEight: MyDevice?
  var theDeviceNine: MyDevice?
  var theDeviceTen: MyDevice?
  var theDeviceEleven: MyDevice?
  var theDeviceTwelve: MyDevice?

  func someMethodThatChecksAllDevices() {
    let check: (inout MyDevice?) -> Void = { deviceRef in
      if let device = deviceRef {
        device.initDevice()
        if !device.selfTest() {
          deviceRef = nil
        }
      }
    }
    check(&theDeviceOne)
    check(&theDeviceTwo)
    check(&theDeviceThree)
    check(&theDeviceFour)
    check(&theDeviceFive)
    check(&theDeviceSix)
    check(&theDeviceSeven)
    check(&theDeviceEight)
    check(&theDeviceNine)
    check(&theDeviceTen)
    check(&theDeviceEleven)
    check(&theDeviceTwelve)
  }
}