스위프트 : 가드 vs if let
저는 Swift에서 Optionals에 대해 읽었으며, if let
Optional이 값을 가지고 있는지 확인하는 데 사용되는 예제를 보았습니다. 그리고 만약 그렇다면 – 언 래핑 된 값으로 무언가를하십시오.
그러나 Swift 2.0에서는 키워드 guard
가 주로 사용되는 것을 보았습니다 . if let
Swift 2.0에서 제거 되었는지 아니면 여전히 사용할 수 있는지 궁금합니다 .
나는 포함 내 프로그램을 변경해야합니다 if let
에를 guard
?
if let
와 guard let
비슷한 역할을하지만, 서로 다른 목적.
의 "else"케이스 guard
는 현재 범위를 종료해야합니다. 일반적으로 이는 return
프로그램을 호출 하거나 중단 해야 함을 의미합니다 . guard
나머지 함수를 중첩하지 않고도 조기 반환을 제공하는 데 사용됩니다.
if let
범위를 중첩하고 특별한 것은 필요하지 않습니다. 할 수 return
있거나 할 수 없습니다.
일반적으로 if-let
블록이 함수의 나머지 부분이되거나 해당 else
절에 a return
또는 abort가 있으면 guard
대신 사용해야합니다 . 이것은 종종 (적어도 내 경험상) 의심스러운 경우 guard
일반적으로 더 나은 대답 임을 의미 합니다. 그러나 if let
여전히 적절한 상황이 많이 있습니다.
가드는 선명도 를 향상시킬 수 있습니다.
가드를 사용 하면 가드가 성공할 가능성 이 훨씬 더 높으며 성공 하지 못하면 범위를 일찍 종료하는 것이 다소 중요합니다 . 배열이 비어 있는지 여부에 따라 파일 / 이미지가 있는지 확인하는 것과 같습니다.
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
if-let으로 위의 코드를 작성하면 읽기 개발자에게 50-50 이상임을 전달합니다. 하지만 가드를 사용하면 코드 에 명확성 을 추가 하고 이것이 95 %의 시간 동안 작동 할 것으로 예상한다는 것을 의미합니다. 실패한 경우 이유를 모르겠습니다. 그럴 가능성은 거의 없지만 ...이 기본 이미지를 대신 사용하거나 잘못된 내용을 설명하는 의미있는 메시지로 단언 할 수 있습니다!
guard
그들이 부작용을 일으킬 때 s를 피하고 , 가드는 자연스러운 흐름 으로 사용되어야 합니다.else
절이 부작용을 유발할 때 가드를 피하십시오 . 가드 는 코드가 제대로 실행 되는 데 필요한 조건을 설정 하여 조기 종료를 제공합니다.당신은에서 긍정적 인 지점에서 상당한 계산, 리팩토링을 수행 할 때
if
A와guard
문과의 대체 값을 반환else
절From : Erica Sadun의 Swift Style 책
또한 위의 제안과 깨끗한 코드의 결과 로 실패한 가드 문에 어설 션을 추가하기를 원하거나 필요로 할 가능성 이 더 높으며 가독성이 향상되고 예상했던 것을 다른 개발자에게 분명하게합니다.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS assertionFailure("Missing \(selectedImageName) asset") return } guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO return }
From : Erica Sadun의 Swift Style 책 + 일부 수정
( if-let
s에 대한 asserts / 전제 조건을 사용 하지 않습니다. 옳지 않은 것 같습니다)
경비원을 사용하면 운명의 피라미드 를 피하여 선명도를 높일 수 있습니다 . Nitin의 답변을 참조하십시오 .
Guard는 새 변수를 만듭니다.
아무도 잘 설명하지 못했다고 생각하는 중요한 차이점이 하나 있습니다.
모두 guard let
와 if let
포장을 벗긴 변수 그러나
와 guard let
당신이 작성 하는 새로운 변수 가 존재 외부 else
문을.
와 if let
당신이 작성되지 않은 새로운 가변 후 다른 문 만 입력 코드 블록을 경우 옵션이 아닌 무기 호입니다. 새로 생성 된 변수 는 코드 블록 내부 에만 존재합니다 .
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
if let
do 에 대한 자세한 내용은 다음을 참조하십시오. 선택적 바인딩의 재 선언이 오류를 생성하지 않는 이유
가드는 범위를 종료 해야합니다.
(Rob Napier의 답변에서도 언급 됨) :
func 안에guard
정의 해야 합니다. 주요 목적은 조건이 충족되지 않는 경우 범위를 중단 / 반환 / 종료 하는 것입니다.
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
들어 if let
당신은 어떤 FUNC 내부에 그것을 할 필요가 없습니다 :
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
사용 if-let
시기와 사용시기 guard
는 종종 스타일의 문제입니다.
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
항목의 선택적 배열 ( var optionalArray: [SomeType]?
) 0
이 있고 배열이 nil
(설정되지 않음) 또는 count
배열에 값이있는 경우 (설정 됨) 를 반환해야 한다고 가정합니다 .
다음을 사용하여 if-let
다음 과 같이 구현할 수 있습니다 .
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
if let array = optionalArray {
return array.count
}
return 0
}
또는 다음과 같이 사용하십시오 guard
.
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
guard let array = optionalArray else {
return 0
}
return array.count
}
예제는 기능적으로 동일합니다.
guard
정말로 빛나는 곳 은 데이터 유효성 검사와 같은 작업이 있고 잘못된 경우 함수가 조기에 실패하기를 원할 때입니다.
if-let
유효성 검사 완료에 가까워 질 때 일련의 s 를 중첩하는 대신 실패 경로가 모두 이미 반환되었으므로 "성공 경로"와 이제 성공적으로 바인딩 된 옵션은 모두 메서드의 주요 범위에 있습니다.
일부 (최적화되지 않은) 코드로 가드 문의 유용성을 설명하려고 노력할 것입니다.
이름, 성, 이메일, 전화 번호 및 비밀번호로 사용자 등록을위한 텍스트 필드의 유효성을 검사하는 UI가 있습니다.
textField에 유효한 텍스트가 포함되지 않은 경우 해당 필드를 firstResponder로 만들어야합니다.
다음은 최적화되지 않은 코드입니다.
//pyramid of doom
func validateFieldsAndContinueRegistration() {
if let firstNameString = firstName.text where firstNameString.characters.count > 0{
if let lastNameString = lastName.text where lastNameString.characters.count > 0{
if let emailString = email.text where emailString.characters.count > 3 && emailString.containsString("@") && emailString.containsString(".") {
if let passwordString = password.text where passwordString.characters.count > 7{
// all text fields have valid text
let accountModel = AccountModel()
accountModel.firstName = firstNameString
accountModel.lastName = lastNameString
accountModel.email = emailString
accountModel.password = passwordString
APIHandler.sharedInstance.registerUser(accountModel)
} else {
password.becomeFirstResponder()
}
} else {
email.becomeFirstResponder()
}
} else {
lastName.becomeFirstResponder()
}
} else {
firstName.becomeFirstResponder()
}
}
위에서 볼 수 있듯이 모든 문자열 (firstNameString, lastNameString 등)은 if 문의 범위 내에서만 액세스 할 수 있습니다. 그래서이 "파멸의 피라미드"를 생성하고 가독성과 이동의 용이성을 포함하여 많은 문제를 가지고 있습니다 (필드의 순서가 변경되면이 코드의 대부분을 다시 작성해야합니다).
guard 문 (아래 코드에서)을 사용하면 이러한 문자열이 외부에서 사용 가능 {}
하고 모든 필드가 유효한 경우 사용 된다는 것을 알 수 있습니다 .
// guard let no pyramid of doom
func validateFieldsAndContinueRegistration() {
guard let firstNameString = firstName.text where firstNameString.characters.count > 0 else {
firstName.becomeFirstResponder()
return
}
guard let lastNameString = lastName.text where lastNameString.characters.count > 0 else {
lastName.becomeFirstResponder()
return
}
guard let emailString = email.text where
emailString.characters.count > 3 &&
emailString.containsString("@") &&
emailString.containsString(".") else {
email.becomeFirstResponder()
return
}
guard let passwordString = password.text where passwordString.characters.count > 7 else {
password.becomeFirstResponder()
return
}
// all text fields have valid text
let accountModel = AccountModel()
accountModel.firstName = firstNameString
accountModel.lastName = lastNameString
accountModel.email = emailString
accountModel.password = passwordString
APIHandler.sharedInstance.registerUser(accountModel)
}
필드의 순서가 변경되면 각 코드 줄을 위나 아래로 이동하면됩니다.
이것은 매우 간단한 설명이자 사용 사례입니다. 도움이 되었기를 바랍니다!
기본적인 차이점
가드 렛
- 범위에서 초기 존재 프로세스
- return, Throw 등과 같은 기존 점수가 필요합니다.
- 범위 밖에서 액세스 할 수있는 새 변수를 만듭니다.
하자면
- 범위 밖으로 액세스 할 수 없습니다.
- 진술을 반환 할 필요가 없습니다. 하지만 우리는 쓸 수 있습니다
참고 : 둘 다 Optional 변수의 래핑을 해제하는 데 사용됩니다.
내가 본 가장 명확한 설명은 Github Swift Style Guide에 있습니다 .
if
깊이 수준을 추가합니다.
if n.isNumber {
// Use n here
} else {
return
}
guard
하지 않습니다 :
guard n.isNumber else {
return
}
// Use n here
가드 문은 하나 이상의 조건이 충족되지 않는 경우 범위 밖으로 프로그램 제어를 전송하는 데 사용됩니다.
가드 문의 조건 값은 Bool 유형이거나 Bool에 브리지 된 유형이어야합니다. 조건은 선택적 바인딩 선언 일 수도 있습니다.
가드 문은 다음과 같은 형식을 갖습니다.
guard condition else {
//Generally return
}
- 옵션 바인딩 으로도 인기
- 옵션 개체에 액세스하는 우리가 사용 허락한다면
if let roomCount = optionalValue {
print("roomCount available")
} else {
print("roomCount is nil")
}
나는 밥과 함께 스위프트에게서 이것을 배웠다 ..
일반적인 Else-If
func checkDrinkingAge() {
let canDrink = true
if canDrink {
print("You may enter")
// More Code
// More Code
// More Code
} else {
// More Code
// More Code
// More Code
print("Let me take you to the jail")
}
}
Else-If 관련 문제
- 중첩 된 괄호
- 오류 메시지를 찾기 위해 모든 줄을 읽어야합니다.
Guard Statement A guard block only runs if the condition is false, and it will exit out of the function through return. If the condition is true, Swift ignores the guard block. It provides an early exit and fewer brackets.+
func checkDrinkProgram() {
let iCanDrink = true
guard iCanDrink else {
// if iCanDrink == false, run this block
print("Let's me take you to the jail")
return
}
print("You may drink")
// You may move on
// Come on.
// You may leave
// You don't need to read this.
// Only one bracket on the bottom: feeling zen.
}
Unwrap Optionals with Else-If
A guard statement is not only useful for replacing a typical conditional block with an else-if statement, but also great for unwrapping optionals by minimizing the number of brackets. To compare, let's first begin how to unwrap multiple optionals with else-if. First, let us create three optionals that will be unwrapped.
var publicName: String? = "Bob Lee"
var publicPhoto: String? = "Bob's Face"
var publicAge: Int? = nil
The Worst Nightmare
func unwrapOneByOne() {
if let name = publicName {
if let photo = publicPhoto {
if let age = publicAge {
print("Bob: \(name), \(photo), \(age)")
} else {
print("age is mising")
}
} else {
print("photo is missing")
}
} else {
print("name is missing")
}
}
The code above certainly works but violates the DRY principle. It's atrocious. Let us break it down.+
Slightly Better The code below is more readable than above.+
func unwrapBetter() {
if let name = publicName {
print("Yes name")
} else {
print("No name")
return
}
if let photo = publicPhoto {
print("Yes photo")
} else {
print("No photo")
return
}
if let age = publicAge {
print("Yes age")
} else {
print("No age")
return
}
}
Unwrap with Guard The else-if statements can be replaced with guard.+
func unwrapOneByOneWithGuard() {
guard let name = publicName else {
print("Name missing")
return
}
guard let photo = publicPhoto else {
print("Photo missing")
return
}
guard let age = publicAge else {
print("Age missing")
return
}
print(name)
print(photo)
print(age)
}
Unwrap Multiple Optionals with Else-If So far, you've been unwrapping optionals one by one. Swift allows us to unwrap multiple optionals at once. If one of them contains nil, it will execute the else block.
func unwrap() {
if let name = publicName, let photo = publicPhoto, let age = publicAge {
print("Your name is \(name). I see your face right here, \(photo), you are \(age)")
} else {
// if any one of those is missing
print("Something is missing")
}
}
Be aware that when you unwrap multiple optionals at once, you can't identify which contains nil
Unwrap Multiple Optionals with Guard Of course, we should use guard over else-if.+
func unwrapWithGuard() {
guard let name = publicName, let photo = publicPhoto, let age = publicAge else {
// if one or two of the variables contain "nil"
print("Something is missing")
return
}
print("Your name is \(name). I see your, \(photo). You are \(age).")
// Animation Logic
// Networking
// More Code, but still zen
}
참고URL : https://stackoverflow.com/questions/32256834/swift-guard-vs-if-let
'program story' 카테고리의 다른 글
피카소의 애니메이션 로딩 이미지 (0) | 2020.08.14 |
---|---|
Linux에서 GDB를 시작하는 동안 명령 줄 인수를 어떻게 전달합니까? (0) | 2020.08.14 |
React Native에서 뷰의 배경색을 투명하게 설정하는 방법 (0) | 2020.08.14 |
IEnumerable 초기화 (0) | 2020.08.14 |
Android의 strings.xml 파일 오류 (0) | 2020.08.14 |