演员价值&从一行获得财产

时间:2016-01-31 13:11:19

标签: swift

我想将以下几行写成一行语句:

var myBool = false
if let myButton = myView.subView.button as? MyButton {
    myBool = !myButton.isValid
}

是否有可能以这种方式做到这一点,如果myButton不是MyButton的类型,那么我的所有内容都会在短语句中返回false?

2 个答案:

答案 0 :(得分:1)

如果你真的想要它在一行,你可以做这样的事情:

let myBool = !((myView.subView.button as? MyButton)?.isValid ?? true)

这是我能够提出的最简洁的方式,具有您概述的预期行为。但是,它远非易读。

然而,想要采用单行方法的明显理由可能是myBool可以用let声明为常量,对吗?

这里的替代方案可能是一种方法:

func isValidButton(testView: UIView) -> Bool {
    guard let button = testView as? MyButton else {
        return false
    }
    return button.isValid
}

所以这是多行,但人们更容易阅读这里发生的事情。在调用的地方,它仍然是一行,并允许你的布尔变量let声明:

let myBool = !isValidButton(myView.subView.button)

请记住,这甚至不必成为课堂上的一种方法。如果您只需要一个位置,它就可以是具有局部范围的闭包。

func viewDidLoad() {
    super.viewDidLoad()

    let isValidButton = { (testView: UIView) -> Bool in
        guard let button = testView as? MyButton else {
            return false
        }
        return button.isValid
    }

    let myBool = !isValidButton(myView.subView.button)

    // do some things
}

作为一个注释,我只假设您的MyButton继承自UIViewUIView可能是myView.subView.button被宣布为返回。实际上,你的isValidButton()闭包应该采用myView.subView.button返回的任何类型的参数(可能是UIButton),并且可能是该类型是MyButton的父类。或者它是MyButton符合的协议。

答案 1 :(得分:1)

1-liner的另一个选择是使用 nil coalescing operator map来应用否定:

let myBool = ((myView.subView.button as? MyButton)?.isValid).map{!$0} ?? false