如何在Swift中使用guard子句,让代码更干净

  • 本文关键字:代码 子句 guard Swift swift
  • 更新时间 :
  • 英文 :


我在我的项目中有以下代码:

//code used in my NEXT button
let errorMessage:String = validateAllFields()
if ( errorMessage != "" ) {
AlertActions.showBasicAlert(erroParaExibir: errorMessage, currentView: self)
return
}
...more code to be executed

//code to validate if all fields are empty
func validateAllFields() -> String {        
var errorMessage = ""
if( nomeAnimalTextField.text == ""){
errorMessage = "Preencha o nome do animal"
} else if( microchipAnimalTextField.text == ""){
errorMessage = "Preencha o microchip do animal"
} else if( microchipAnimalTextField.text!.trim().count < 15){
errorMessage = "Microchip do animal deve possuir 15 posições númericas"
} else if( mesNascimentoTextField.text == ""){
errorMessage = "Preencha o mês do nascimento"
} else if( anoNascimentoTextField.text == ""){
errorMessage = "Preencha o ano de nascimento"
}
return errorMessage
}
下面的代码是我的保护子句
if ( errorMessage != "" ) {
AlertActions.showBasicAlert(erroParaExibir: errorMessage, currentView: self)
return
}

如果条件不满足,返回值将保护剩余的代码不被执行。

我想知道如何仅使用validateAllFields()并使用"return"插入if条件部分代码在这个函数中,这可能吗?

我喜欢John Montgomery的回答,但是让错误是错误而不是字符串也很有帮助。然后你可以使用Swift的错误处理系统。不返回String,而是抛出:

struct ValidationError: Error {
var localizedDescription: String
init(_ message: String) { self.localizedDescription = message }
}
func validateAllFields() throws {
if( nomeAnimalTextField.text == "") { throw ValidationError("Preencha o nome do animal") }
if( microchipAnimalTextField.text == ""){ throw ValidationError("Preencha o microchip do animal") }
if( microchipAnimalTextField.text!.trim().count < 15) {
throw ValidationError("Microchip do animal deve possuir 15 posições númericas")
}
if( mesNascimentoTextField.text == "") { throw ValidationError("Preencha o mês do nascimento") }
if( anoNascimentoTextField.text == "") { throw ValidationError("Preencha o ano de nascimento") }
}

当你想检查这个时,使用do/catch:

do {
try validateAllFields()
//    ...more code to be executed
} catch {
AlertActions.showBasicAlert(erroParaExibir: error.localizedDescription, 
currentView: self)
}

或者您可以将catch移动到顶部并添加return,如果代码中没有其他内容可以生成错误。(或者您可以通过将此方法标记为throws来让错误进一步冒泡。)

我还建议showBasicAlert接受一个错误,而不仅仅是一个字符串。

在这里使用throw的好处是它可以灵活地处理更复杂的问题。例如,您可以提取一些逻辑:

func validateNonEmpty(_ field: UITextField, or message: String) throws {
if field.text == "" { throw ValidationError(message) }
}
func validateField(_ field: UITextField, atLeastLength minLength: Int, or message: String) throws {
if field.text!.trim().count < minLength { throw ValidationError(message) }
}

然后将验证器写入:

func validateAllFields() throws {
try validateNonEmpty(nomeAnimalTextField, or: "Preencha o nome do animal")
try validateNonEmpty(microchipAnimalTextField, or: "Preencha o microchip do animal")
try validateField(microchipAnimalTextField, atLeastLength: 15,
or: "Microchip do animal deve possuir 15 posições númericas")
try validateNonEmpty(mesNascimentoTextField, or: "Preencha o mês do nascimento")
try validateNonEmpty(anoNascimentoTextField, or: "Preencha o ano de nascimento")
}

我不确定这是否可能与一个警卫,至少不是在一个步骤。最简单的方法是将验证器更改为返回可选值,并使用nil而不是空字符串作为默认值:

func validateAllFields() -> String? {        
var errorMessage: String?
// rest of code is the same
return errorMessage
}

然后使用if let进行测试:

if let errorMessage = validateAllFields() {
AlertActions.showBasicAlert(erroParaExibir: errorMessage, currentView: self)
return
}

最新更新