Operator : 특정 값을 확인 / 변경 / 조합 하기 위해 사용하는 간단한 symbol / phrase.
-a)
!b)c!)2 + 3)a ? b : c)Operator 가 연산하는 값들이 operands (피연산자)
=
let b = 10
var a = 5
a = b
// a is now equal to 10
let (x, y) = (1, 2) // tuple 값 할당
C, obj-c 와는 다르게 값 자체를 return 하지 않음. 이를 통해 equal to operator == 를 사용해야 하는 시점에 assignment operator = 를 실수로 사용하는 것을 방지해줌
if x = y {
// ❗️ x = y 가 값을 return 하지 않기 때문에 유효하지 않음
}
Swift 는 네 개의 표준 arithmetic 연산자 지원
+-*/C, obj-c 와는 다르게 기본적으로 overflow 를 허용하지 않으나 overflow operators (&+, …) 를 사용할 수 있음.
Addition operator 는 String concatenation 에 지원됨
"hello, " + "world" // "hello, world"
a % b : 나머지 연산.
a = (b x some multiplier) + remainder. 이 때 multiplier 는 가장 큰 숫자여야 함
9 % 4 // 1
-9 % 4 // -1
// -9 = (4 * -2) + (-1)
prefixed - 로 부호를 바꿀 수 있음
let three = 3
let minusThree = -three // minusThree equals -3
변화 없이 해당 값을 그대로 return
let minusSix = -6
let alsoMinusSix = +minusSix // alsoMinusSix equals -6
assignment = 와 다른 operator 를 조합한 연산자. 값을 리턴하지 않음
var a = 1
a += 2 // a is now equal to 3
let b = a += 2 // ❗️ invalid
Bool 값을 리턴함
a == ba != ba > ba < ba >= bLess than or equal to a <= b
===!==같은 타입과 개수의 값들을 가진 tuple 을 비교할 수 있음. Tuple 은 왼쪽 -> 오른쪽 순서대로 값 하나씩 비교됨. 모든 값이 다 같은 경우에만 같은 것으로 판단됨. 각 값에 operator 를 적용할 수 있는 경우에만 비교될 수 있음.
(1, "zebra") < (2, "apple") // true because 1 is less than 2; "zebra" and "apple" aren't compared. 첫 번째 값이 우선됨
(3, "apple") < (3, "bird") // true because 3 is equal to 3, and "apple" is less than "bird". 첫 번째 값이 같아서 두 번째 값을 비교
(4, "dog") == (4, "dog") // true because 4 is equal to 4, and "dog" is equal to "dog"
("blue", -1) < ("purple", -7) // OK: Evaluates to true. 첫 번째 값으로 판단
("blue", false) < ("purple", true) // ❗️ Error: Can't use < to compare Boolean values.
Swift 표준 라이브러리에서 tuple 비교는 7개보다 적은 tuple 에만 적용되기 때문에 필요하다면 직접 구현해야 함
question ? answer1 : answer2 형태.
if question {
answer1
} else {
answer2
}
간결하게 작성할 수 있으나 많이 사용될 경우 가독성을 떨어뜨릴 수 있음에 주의.
a ?? b 는 optional a 의 값이 있으면 unwrap 하고 없다면 b 를 리턴
a != nil ? a! : b
short-circuit evaluation : a 가 nil 이 아닐 경우 b 는 연산되지 않음
a...b : b 를 포함한 범위까지
for index in 1...5 {
print(index)
}
// 1 ~ 5 까지 출력됨
a..<b : b 를 포함하지 않는 범위까지. 배열 iterate 할 때 편함
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print("Person \(i + 1) is called \(names[i])")
}
한 방향으로 가능한 한 많은 범위를 표현할 수 있음.
...a 형태 : 어디서 시작해야 하는지 모르기 때문에 iterate 할 수 없음a... 형태 : 어디서 시작해야 하는지 알기 때문에 iterate 할 수 있지만 범위가 무한정하기 때문에 iteration 을 끊을 명시적인 조건이 필요함for name in names[2...] {
print(name)
}
// Brian
// Jack
for name in names[...2] {
print(name)
}
// Anna
// Alex
// Brian
for name in names[..<2] {
print(name)
}
// Anna
// Alex
let range = ...5
range.contains(7) // false
range.contains(4) // true
range.contains(-1) // true
Bool 값을 수정 / 조합함
!aa && ba || bBool 값을 toggle 하는 prefix operator. not ~ 라고 읽음
let allowedEntry = false
if !allowedEntry { print("ACCESS DENIED") }
두 값이 모두 true 여야 true 가 됨. 첫 번째 조건이 false 인 경우 두 번째 조건은 연산되지 않음. (short-circuit evaluation)
let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "ACCESS DENIED".
두 값중에 하나라도 true 인 경우 true. 첫 번째 조건이 true 인 경우 두 번째 조건은 연산되지 않음 (short-circuit evaluation)
let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"
여러 개의 logical operator 를 엮어서 긴 표현을 작성할 수 있음
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"
// left-associative : 여러 logical operator 는 가장 왼쪽의 subexpression 을 먼저 연산
// ((enteredDoorCode && passedRetinaScan) || hasDoorKey) || knowsOverridePassword 과 같음
명시적으로 괄호를 써서 읽기 쉽게 하는 것이 유용함. 항상 가독성이 간결함보다 선호됨.
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"