我有一个用于文本验证的枚举,定义如下:
E
我的enum Validity {
case valid
case invalid(reason: String)
}
具有检查文本输入并返回TextValidator
的功能:
Validity
这很方便,因为如果发生错误,我可以毫不费力地向用户显示验证失败的原因。
但是,在许多情况下,我只需要布尔检查字符串是否有效-例如用于启用/禁用提交按钮。我现在为此使用的代码是:
func validate(_ string: String) -> Validity
这有点不好看,因此,我宁愿写这样的东西:
let validity = validator.validate("user input string")
submitButton.isEnabled = (validity == .valid)
或更短:
let isValid: Bool = validator.validate("user input string")
submitButton.isEnabled = isValid
作为“快速修复”,我在submitButton.isEnabled = validator.validate("user input string")
枚举上定义了一个计算的布尔属性isValid
,因此我至少可以写:
Validity
但是对我来说,将submitButton.isEnabled = validator.validate("user input string").isValid
附加到验证结果上有点冗长,而我非常希望直接检查有效性并将其用作布尔值,以用于需要通过类型的布尔值的上下文中推断。
所以我的问题是:
.isValid
?或者如果不是:您能想到另一种保留了两者优势的方法吗?Bool和枚举类型?
答案 0 :(得分:1)
您可以通过重载validate
函数来返回Bool
来实现这一点。
enum Validity {
case valid
case invalid(reason: String)
}
// Example validate function
func validate(_ string: String) -> Validity {
if string.count < 5 {
return .valid
} else {
return .invalid(reason: "String too long")
}
}
// Overloaded function which returns Bool
func validate(_ string: String) -> Bool {
let validity: Validity = validate(string)
if case .valid = validity {
return true
} else {
return false
}
}
// Swift expects the result of validate to be a Bool, so it calls the
// (String) -> Bool version of validate
let b1: Bool = validate("this")
print(b1)
true
// Here, the result of validate is used in an if, so Swift is expecting
// a Bool result and calls the (String) -> Bool version of validate
if validate("this is a test") {
print("the string is valid")
} else {
print("the string is invalid")
}
the string is invalid
let v: Validity = validate("what about this one?")
switch v {
case .valid:
print("valid")
case .invalid(let reason):
print("invalid: \(reason)")
}
invalid: String too long