단락평가
논리평가식에서 결과 도출에 필요한 최소한의 논리식만 평가한다.
true || true
// 왼쪽부터 평가하는데, ||(or)로 연결되어있기 때문에 뒤의 표현식이 true or false 에 상관없이 항상 true가 되기 때문에 뒤의 표현식은 검사하지 않는다.
false && true
// 이도 마찬가지로 &&(and)로 연결되어있기 때문에 뒤의 표현식인 true는 평가하지 않는다.
사이드이펙트
사이드 이펙트의 사전적인 의미는 '원래 의 목적과 다른 효과 또는 부작용'이라는 상태를 말한다.
마치 고혈압 약을 먹었는데 머리가 풍성해지는것과 같은..?
꼭 부정적인일만은 아니다. 하지만 좋은 결과를 나타낸다고해서 좋은 사이드 이펙트는 없다.
var some = 0
func checking() -> Bool{
some += 1
return true
}
if(checking() || checking() && ...){
//...
}
// if문 내부에서 checking함수를 사용하면 단락평가와 조건식에 따라 checking이라는 함수가 실행되는 횟수가 달라질 수 있다.
무언가를 검사하기위해 checking이라는 함수를 만들 수 있다. 하지만 이 함수는 외부변수인 some에 1을 더하고있고, checking함수를 몇번 실행시키냐에 따라서 some의 value가 달라질 수 있다.
check를 하기위해 함수를 만들었지만 check의 목적에 맞지않게 다른 상태 변화가 나타나고 있으니 이도 사이드이펙트라고 할 수 있다.
단락평가와 사이드이펙트
var idResult = 0
var passwordResult = 0
func idCheck() -> Bool{
idResult += 1
return true
}
func passwordCheck() -> Bool{
passwordResult += 1
return true
}
if(idCheck() && passwordCheck() && false || idCheck() && passwordCheck()){
}
print("id = \(idResult), password = \(passwordResult)")
// id = 2, password = 2
이와 같은 경우 왼쪽부터 천천히 idCheck(), passwordCheck(), idCheck(), passwordCheck(), 가 실행될것이다.
근데 만약 중간의 ||가 &&로 바뀐다면?
if(idCheck() && passwordCheck() && false && idCheck() && passwordCheck()){
}
print("id = \(idResult), password = \(passwordResult)")
// id = 1, password = 1
이렇게 변화한다. 왼쪽부터 하나씩 실행해나가다가 false를 만나고, 모두 &&로 연결되어 있으니 실행해볼 필요가 없기 때문이다.
if(idCheck() || passwordCheck() && idCheck() || false && passwordCheck()){
}
print("id = \(idResult), password = \(passwordResult)")
// id = 1, password = 0
이처럼 실행되는 이유는 첫 번째 idCheck()를 실행하면 True가 나오고, 이외네는 전부 ||로 연결되어있으니 뒤에서 뭐가나오던 검사 할 필요가 없어진다. ||가 &&연산보다 늦게 실행되기 때문이다. &&연산을 모두 처리해보면
true || true || false 가 나오게되고, 이는 어차피 맨 앞의 idCheck()가 true임을 알게되는 순간 뒤의 조건식들은 확인할 필요가 없어진다.
이처럼 표현식에 따른 단락평가가 달라지고, 그에따른 사이드이펙트가 발생한다.