Swift에서 논리 평가식(&&, ||)을 계산할 때는 단락 평가(Short-circuit Evaluation) 방식을 사용합니다.
(단락 평가는 논리 평가식에서 결과 도출을 위해 최소한의 논리식만을 평가하는 방식입니다.)
✅ 논리 연산자에서 사용되는 단락 평가
false &&
의 경우 && 뒤에 어떠한 논리값이 오더라도 false이기 때문에 단락 평가 방식이 사용됩니다.
true ||
의 경우 || 뒤에 어떠한 논리값이 오더라도 true이기 때문에 단락 평가 방식이 사용됩니다.true && true // true true && false // false false && true // false 단락 평가 사용 false && false // false 단락 평가 사용 true || true // true 단락 평가 사용 true || false // true 단락 평가 사용 false || true // true false || false // false
이러한 단락 평가 방식은 결과 도출을 위해 최소한의 논리식으로만 평가하기 때문에 코드의 연산 속도(성능)가 조금 증가한다는 장점을 가지고 있습니다.
하지만 단락 평가에서 발생할 수 있는 문제 또한 존재합니다.
✅ 단락 평가에서 발생하는 문제
논리 연산자 ||(OR) 앞의 값이 true이면 단락 평가가 발생하기 때문에 논리 연산자 ||(OR) 뒤의 코드는 읽지 않습니다.
var aCount = 0 var bCount = 0 func aaa() -> Bool{ aCount += 1 // 사이드 이팩트 발생 return true } func bbb() -> Bool{ bCount += 1 // 사이드 이팩트 발생 return true } if aaa() || bbb(){ } aCount // 1 bCount // 0
논리 연산자 &&(AND)의 경우에는 앞의 값이 true라 해도 논리 연산자 &&(AND) 뒤의 코드를 읽기 때문에 값이 다르게 나옵니다.
var aCount = 0 var bCount = 0 func aaa() -> Bool{ aCount += 1 // 사이드 이팩트 발생 return true } func bbb() -> Bool{ bCount += 1 // 사이드 이팩트 발생 return true } if aaa() && bbb(){ } aCount // 1 bCount // 1
✅ 단락 평가에서 발생하는 문제 해결 방법
논리 연산자에 따라 값이 바뀌게 되면 예상치 못한 에러 및 결과를 반환받을 수 있습니다.
때문에 논리 연산자를 사용할 때는 오류가 없도록 표현식을 미리 실행하는 방식으로 코드를 수정하는 것이 좋습니다.
(표현식을 미리 실행할 경우 사이드 이펙트 값이 고정되기 때문에 값이 바뀌는 경우를 예방할 수 있습니다.)var aCount = 0 var bCount = 0 func aaa() -> Bool{ aCount += 1 // 사이드 이팩트 발생 return true } func bbb() -> Bool{ bCount += 1 // 사이드 이팩트 발생 return true } var A = aaa() // aCount = 1 var B = bbb() // bCount = 1 if A || B{ } aCount // 1 bCount // 1 if A && B{ } aCount // 1 bCount // 1
⚙️ 참고
대표적인 논리 연산자인 &&(AND) ||(OR)의 경우에도 우선순위가 존재합니다.
1순위는 &&(AND)이며, 2순위가 ||(OR)입니다.사이드 이펙트: 사이트 이펙트란 함수 코드 내부에서 코드 외부의 변수에 접근하여 값을 변동하는 개념입니다.
var sum = 0 func xxx(){ sum += 1 // 사이드 이펙트 발생 }