简化swift中的嵌套if

简化swift中的嵌套if,swift,Swift,我的应用程序有一个名为MyDevice的类,我用它与硬件通信。此硬件是可选的,实例变量也是可选的: var theDevice:MyDevice = nil 然后,在应用程序中,我必须初始化设备(用于通信),然后执行自检以检查其可用性和执行准备情况。如果此操作失败,则设备不可用/无法访问/出现故障 这是我过于复杂的代码。我正在寻找如何简化它 if let device = self.theDevice { device.initDevice() if (!device.sel

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

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

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

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

    if (!device.selfTest())
    {
        self.theDevice = nil;
    }
}
我试图在if语句中使用&&组合所有测试,但失败了。
问题是,在函数开始时,我有12个用于各种设备。它占用了很多空间而且很脏。如何在Swift中组合这些语句?

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

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


但是我更喜欢
如果让
为可读性选择展开。

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

if case let selfTest? = theDevice?.initDevice().selfTest() where !selfTest {
    theDevice = nil
}
另一个选项是使
initDevice
执行
自检
,然后返回

所有这些都假设
initDevice
是您的代码,或者您可以通过某种方式进行编辑

如果不可编辑,则始终可以进行扩展,并在其中创建新方法:

extension TheDeviceClass {

    func initAndTest() -> Bool {
        initDevice()
        return selfTest()
    }
}
然后用这样的方式来称呼它:

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

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

< P>我认为你应该改变你的MyDebug实现,通过定义一个<强>可初始化的初始化器并做里面的所有检查来减少代码的冗余。因此,如果初始化失败,您将得到一个nil,只需将其分配给另一个类的相关属性,甚至不需要检查12个设备的方法

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

  func initDevice() {
    // initialization
  }

  init?() {
    self.initDevice()
    if !self.selfTest() {
      return nil
    }
  }
}
如果您不想太多地更改代码,可以定义一个闭包来减少这些冗余代码,如下所示(它看起来仍然很难看,因此我不建议您这样做。):


“合并所有三个测试”我只看到2个
if
s。第三个条件是什么?而且,它对我来说似乎并不“过于复杂”。我觉得它可读性很强。一个协议和一个func可以调用并传递每个设备,而这些设备可以位于一个数组中iterate@Arc676:谢谢。我改了课文。我的意思是我必须在自检()之前调用initDevice()。虽然看起来数组可能是示例中的解决方案。。。在我的情况下,它真的不是。为什么你不能把这些设备放到一个数组中呢?
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)
  }
}