🔥 논리 연산자

565자
7분

프로그래밍을 하다 보면 여러 조건을 조합하여 결과를 도출해야 하는 경우가 많습니다. 이때 사용하는 것이 바로 논리 연산자인데요. Swift에서는 C 기반 언어에서 볼 수 있는 세 가지 표준 논리 연산자를 제공합니다.

  • 논리 NOT (!a)
  • 논리 AND (a && b)
  • 논리 OR (a || b)

이 연산자들은 truefalse의 불리언 논리 값을 수정하거나 결합할 때 사용합니다.

논리 NOT 연산자

논리 NOT 연산자(!a)는 불리언 값을 반전시켜서 truefalse로, falsetrue로 만듭니다. 이 연산자는 전위 연산자로, 공백 없이 연산할 값 바로 앞에 나타납니다. 다음 예제에서 보듯이 "not a"로 읽을 수 있지요.

let allowedEntry = false
if !allowedEntry {
    print("ACCESS DENIED")
}
// "ACCESS DENIED" 출력
swift

if !allowedEntry 구문은 "허용된 입장이 아니라면"으로 읽을 수 있습니다. allowedEntryfalse일 때, 즉 "허용된 입장이 아닌" 경우에만 다음 줄이 실행됩니다.

불리언 상수와 변수의 이름을 신중하게 선택하면 이중 부정이나 혼란스러운 논리 명제를 피하면서도 코드를 읽기 쉽고 간결하게 유지할 수 있습니다.

논리 AND 연산자

논리 AND 연산자(a && b)는 두 값이 모두 true여야 전체 표현식도 true가 되는 논리식을 만듭니다.

어느 한 값이라도 false이면, 전체 표현식도 false가 됩니다. 사실, 첫 번째 값이 false이면 두 번째 값은 평가조차 되지 않는데, 전체 표현식이 true가 될 가능성이 없기 때문이지요. 이를 단락 평가(short-circuit evaluation)라고 합니다.

다음 예제는 두 개의 Bool 값을 고려하여 두 값이 모두 true일 때만 접근을 허용합니다.

let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// "ACCESS DENIED" 출력
 
swift

논리 OR 연산자

논리 OR 연산자(a || b)는 인접한 두 개의 파이프 문자로 만든 중위 연산자입니다. 두 값 중 하나true여도 전체 표현식이 true가 되는 논리식을 만들 때 사용합니다.

위의 논리 AND 연산자와 마찬가지로, 논리 OR 연산자도 표현식을 고려할 때 단락 평가를 사용합니다. 논리 OR 표현식의 왼쪽이 true이면, 오른쪽은 평가되지 않는데, 전체 표현식의 결과를 바꿀 수 없기 때문이지요.

아래 예제에서는 첫 번째 Bool 값(hasDoorKey)은 false이지만, 두 번째 값(knowsOverridePassword)은 true입니다. 하나의 값이 true이기에 전체 표현식도 true로 평가되어 접근이 허용됩니다.

let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// "Welcome!" 출력
swift

논리 연산자 결합하기

여러 논리 연산자를 결합하여 더 긴 복합 표현식을 만들 수 있습니다.

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// "Welcome!" 출력
swift

이 예제는 여러 개의 &&|| 연산자를 사용하여 더 긴 복합 표현식을 만듭니다. 그러나 &&|| 연산자는 여전히 두 값에 대해서만 작동하므로, 이는 사실 세 개의 작은 표현식이 연결된 것이지요. 이 예제는 다음과 같이 읽을 수 있습니다.

올바른 출입 코드를 입력하고 망막 스캔을 통과했거나, 유효한 출입 키가 있거나, 비상 재정의 비밀번호를 알고 있다면 접근을 허용한다.

enteredDoorCode, passedRetinaScan, hasDoorKey의 값에 따라 처음 두 하위 표현식은 false입니다. 하지만 비상 재정의 비밀번호를 알고 있으므로, 전체 복합 표현식은 여전히 true로 평가됩니다.

명시적 괄호 사용하기

엄격히 필요하지 않을 때에도 괄호를 포함하는 것이 때로는 유용한데, 복잡한 표현식의 의도를 더 쉽게 읽을 수 있게 하기 때문입니다. 위의 출입 허용 예제에서는 복합 표현식의 첫 번째 부분에 괄호를 추가하여 의도를 명확히 하는 것이 유용하지요.

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// "Welcome!" 출력
swift

괄호는 처음 두 값이 전체 논리에서 별도의 가능한 상태의 일부로 간주됨을 분명히 합니다. 복합 표현식의 출력은 변경되지 않지만, 전체적인 의도가 독자에게 더 명확해집니다. 가독성은 항상 간결성보다 우선시되어야 합니다. 괄호가 의도를 명확히 하는 데 도움이 된다면 사용하는게 좋겠죠?

이처럼 논리 연산자를 적절히 활용하면 코드의 논리를 더욱 명확하고 간결하게 표현할 수 있답니다.