我想将以下几行写成一行语句:
var myBool = false
if let myButton = myView.subView.button as? MyButton {
myBool = !myButton.isValid
}
是否有可能以这种方式做到这一点,如果myButton
不是MyButton
的类型,那么我的所有内容都会在短语句中返回false?
答案 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
继承自UIView
而UIView
可能是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