기본 연산자 (Basic Operators)

연산자는 값을 확인, 변경 또는 결합하는 데 사용하는 특수 기호 또는 구문입니다. 예를 들어, 더하기 연산자 (+)는 let i = 1 + 2 에서처럼 두 개의 숫자를 더하고, 논리 AND 연산자 (&&)는 마치 enterDoorCode &&가 RetinaScan을 통과 한 것처럼 두 개의 부울 값을 결합합니다.

Swift는 C와 같은 언어에서 이미 알고있는 연산자를 지원하고 일반적인 코딩 오류를 제거하기 위해 여러 기능을 개선했습니다. 대입 연산자 (=)는 같음 연산자 (==)가 의도 될 때 잘못 사용되는 것을 방지하기 위해 값을 반환하지 않습니다. 산술 연산자 (+,-, *, /, % 등)는 이를 저장하는 타입의 허용 된 값 범위보다 커지거나 작아지는 숫자로 작업 할 때 예기치 않은 결과를 방지하기 위해 값 오버플로를 감지하고 허용하지 않습니다. [Overflow Operators]에 설명 된대로 Swift의 오버플로 연산자를 사용하여 값 오버플로 동작을 선택할 수 있습니다.

Swift는 또한 a .. <b 및 a … b와 같이 C에서 찾을 수 없는 범위 연산자를 값 범위를 표현하기위한 단축키로 제공합니다.

이 장에서는 Swift의 일반적인 연산자에 대해 설명합니다. [Advanced Operators]는 Swift의 고급 연산자를 다루고 사용자 지정 연산자를 정의하고 사용자 지정 유형에 대한 표준 연산자를 구현하는 방법을 설명합니다.

용어 (Terminology)

연산자는 단항, 이진 또는 삼항입니다.

  • 단항 연산자는 단일 대상 (예 : -a)에서 작동합니다. 단항 접두사 연산자는 대상 바로 앞에 나타나고 (예 : !b) 단항 접두사 연산자는 대상 바로 뒤에 나타납니다 (예 : c!).
  • 이항 연산자는 두 대상 (예 : 2 + 3)에서 작동하며 두 대상 사이에 나타나기 때문에 중위입니다.
  • 삼항 연잔자는 3 개의 타켓을 운영합니다. C와 마찬가지로 Swift에는 삼항 연산자 인 삼항 조건 연산자 (a ? b : c) 만 있습니다.

연산자가 영향을 미치는 값은 피연산자입니다. 표현식 1 + 2에서 + 기호는 이항 연산자이고 두 피연산자는 값 1과 2입니다.

할당 연산자 (Assignment Operator)

할당 연산자 (a = b)는 a 값을 b 값으로 초기화하거나 업데이트합니다.

let b = 10
var a = 5
a = b
// a는 10과 같습니다.

할당의 오른쪽이 여러 값을 가진 튜플 인 경우 해당 요소는 한 번에 여러 상수 또는 변수로 분해 될 수 있습니다.

let (x, y) = (1, 2)
// x 는 1 과 같고, y 는 2와 같습니다.

C 및 Objective-C의 할당 연산자와 달리 Swift의 할당 연산자는 자체적으로 값을 반환하지 않습니다. 다음 코드는 잘못된 것입니다.

if x = y {
    // 이것은 잘못된 것입니다. x = y 는 값을 반환하지 않기 때문입니다.
}

이 기능은 같음 연산자 (==)가 실제로 의도 된 경우 할당 연산자 (=)가 실수로 사용되는 것을 방지합니다. if x = y를 유효하지 않게 만들면 Swift는 코드에서 이러한 종류의 오류를 방지하는 데 도움이됩니다.

산술 연산자 (Arithmetic Operators)

Swift는 모든 숫자 유형에 대해 네 가지 표준 산술 연산자를 지원합니다.

  • 더하기 (+)
  • 빼기 (-)
  • 곱하기 (*)
  • 나누기 (/)
1 + 2       // 3
5 - 3       // 2
2 * 3       // 6
10.0 / 2.5  // 4.0

C 및 Objective-C의 산술 연산자와 달리 Swift 산술 연산자는 기본적으로 값 오버플로를 허용하지 않습니다. Swift의 오버 플로우 연산자 (예 : a & + b)를 사용하여 오버 플로우 동작의 가치를 높일 수 있습니다. [오버플로 연산자]를 참조하십시오.

더하기 연산자는 문자열 연결도 지원됩니다.

"hello, " + "world"  // "hello, world"

나머지 연산자 (Remainder Operator)

나머지 연산자 (a % b)는 a에 들어갈 b의 배수를 계산하고 남은 값 (나머지)을 반환합니다.

노트
나머지 연산자 (%)는 다른 언어에서는 modulo operator라고도합니다. 그러나 Swift에서 음수에 대한 동작은 엄밀히 말하면 모듈로 연산이 아니라 나머지라는 것을 의미합니다.

나머지 연산자의 작동 방식은 다음과 같습니다. 9 % 4를 계산하려면 먼저 9에 들어갈 4가 몇 개인 지 계산해야합니다.

9 안에 4를 2 개 넣을 수 있고 나머지는 1 (주황색으로 표시)입니다.

Swift에서는 다음과 같이 작성됩니다.

9 % 4    // 결과 1

a % b에 대한 답을 결정하기 위해 % 연산자는 다음 방정식을 계산하고 나머지를 출력으로 반환합니다.
a = (b x 일부 승수) + 나머지
여기서 어떤 승수는 a 안에 들어갈 b의 가장 큰 배수입니다.
이 방정식에 9와 4를 삽입하면 다음이 생성됩니다.
9 = (4 x 2) + 1
a의 음수 값에 대한 나머지를 계산할 때 동일한 방법이 적용됩니다.

-9 % 4   // -1

방정식에 -9와 4를 넣으면 다음이 생성됩니다.
-9 = (4 x -2) + -1
나머지 값은 -1입니다.
b의 음수 값에 대해서는 b의 부호가 무시됩니다. 즉, a % b와 a % -b는 항상 동일한 답을 제공합니다.

단항 빼기 연산자 (Unary Minus Operator)

숫자 값의 부호는 단항 빼기 연산자라고하는 접두사-를 사용하여 전환 할 수 있습니다.

let three = 3
let minusThree = -three       // minusThree 은 -3
let plusThree = -minusThree   // plusThree 은 3, 또는 "마이너스 마이너스 삼"

단항 빼기 연산자 (-)는 공백없이 값 바로 앞에 추가됩니다.

단항 더하기 연산자 (Unary Plus Operator)

단항 더하기 연산자 (+)는 변경없이 단순히 작동하는 값을 반환합니다.

let minusSix = -6
let alsoMinusSix = +minusSix  // alsoMinusSix 는 -6

단항 더하기 연산자는 실제로 아무 작업도 수행하지 않지만 음수에 단항 빼기 연산자를 사용할 때 양수에 대해 코드에서 대칭을 제공하는 데 사용할 수 있습니다.

복합 할당 연산자 (Compound Assignment Operators)

C와 마찬가지로 Swift는 할당 (=)과 다른 연산을 결합하는 복합 할당 연산자를 제공합니다. 한 가지 예는 더하기 할당 연산자 (+ =)입니다.

var a = 1
a += 2
// a 는 3 과 같습니다.

표현식 a += 2는 a = a + 2의 축약 형입니다. 실제로 더하기와 할당은 두 작업을 동시에 수행하는 하나의 연산자로 결합됩니다.

NOTE
복합 할당 연산자는 값을 반환하지 않습니다. 예를 들어 let b = a += 2라고 쓸 수 없습니다.

비교 연산자 (Comparison Operators)

Swift는 다음 비교 연산자를 지원합니다.

  • 같음 (a == b)
  • 같지 않음 (a != b)
  • 보다 큼 (a > b)
  • 보다 작음 (a < b)
  • 보다 크거나 같음 (a >= b)
  • 보다 작거나 같음 (a <= b)

노트
Swift는 또한 두 개의 identity operators (=== 및 !==)를 제공하며, 두 개체 참조가 모두 동일한 개체 인스턴스를 참조하는지 여부를 테스트하는 데 사용합니다. 자세한 내용은 [identity operators]를 참조하십시오.

각 비교 연산자는 명령문이 참인지 여부를 나타내는 Bool 값을 반환합니다.

1 == 1   // 1과 1은 같음으로 true
2 != 1   // 2는 1과 다름으로 true
2 > 1    // 2는 1 보다 큼으로 true
1 < 2    // 1은 2보다 작음으로 true
1 >= 1   // 1은 1보다 크거나 같음으로  true
2 <= 1   // 2는 1보다 작거나 같지 않음으로 false 

비교 연산자는 if 문과 같은 조건문에서 자주 사용됩니다.

let name = "world"
if name == "world" {
    print("hello, world")
} else {
    print("미안해요 \(name), 나는 당신을 인식할 수 없어요.")
}
// 이름이 실제로 "world"와 같으므로 "hello, world"를 출력합니다.

유형이 같고 값 수가 같은 경우 두 튜플을 비교할 수 있습니다. 튜플은 비교에서 같지 않은 두 값을 찾을 때까지 한 번에 한 값씩 왼쪽에서 오른쪽으로 비교됩니다. 이 두 값이 비교되고 해당 비교 결과가 튜플 비교의 전체 결과를 결정합니다. 모든 요소가 같으면 튜플 자체도 같습니다. 예를 들면 :

(1, "zebra") < (2, "apple")   // 1이 2보다 작기 때문에 참; "얼룩말"과 "사과"는 비교되지 않습니다.
(3, "apple") < (3, "bird")    // 3은 3과 같고 "apple"은 "bird"보다 작기 때문에 참
(4, "dog") == (4, "dog")      // 4는 4와 같고 "dog"는 "dog"와 같으므로 참

위의 예에서 첫 번째 줄에서 왼쪽에서 오른쪽으로 비교 동작을 볼 수 있습니다. 1이 2보다 작기 때문에 튜플의 다른 값에 관계없이 (1, “zebra”)는 (2, “apple”)보다 작은 것으로 간주됩니다. 비교는 이미 튜플의 첫 번째 요소에 의해 결정되기 때문에 “zebra”가 “apple”보다 작지 않은 것은 중요하지 않습니다. 그러나 튜플의 첫 번째 요소가 동일하면 두 번째 요소가 비교됩니다. 이것이 두 번째와 세 번째 줄에서 발생하는 것입니다.

연산자가 각 튜플의 각 값에 적용될 수있는 경우에만 튜플을 주어진 연산자와 비교할 수 있습니다. 예를 들어, 아래 코드에 나와있는 것처럼 <연산자를 사용하여 String 및 Int 값을 비교할 수 있으므로 (String, Int) 유형의 두 튜플을 비교할 수 있습니다. 반대로 <연산자는 Bool 값에 적용 할 수 없기 때문에 유형 (String, Bool)의 두 튜플을 <연산자와 비교할 수 없습니다.>

("blue", -1) < ("purple", 1)        // 참 으로 평가
("blue", false) < ("purple", true)  // 부울값을 비교할 수 없기 때문에 에러

NOTE
Swift 표준 라이브러리에는 요소가 7 개 미만인 튜플에 대한 튜플 비교 연산자가 포함되어 있습니다. 7 개 이상의 요소가있는 튜플을 비교하려면 비교 연산자를 직접 구현해야합니다.

삼항 조건부 연산자 (Ternary Conditional Operator)

삼항 조건 연산자는 질문? 형식을 취하는 세 부분으로 구성된 특수 연산자입니다. 답변1 : 답변2. 질문이 참인지 거짓인지에 따라 두 표현 중 하나를 평가하는 지름길입니다. 질문이 참이면 answer1을 평가하고 값을 반환합니다. 그렇지 않으면 answer2를 평가하고 그 값을 반환합니다.

삼항 조건 연산자는 아래 코드의 축약 형입니다.

if question {
    answer1
} else {
    answer2
}
// question ? answer1 : answer2

다음은 표 행의 높이를 계산하는 예입니다. 행에 헤더가있는 경우 행 높이는 콘텐츠 높이보다 50 포인트 더 커야하며 행에 헤더가 없으면 20 포인트 더 높아야합니다.

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight 는 90 입니다.

위의 예는 아래 코드의 축약 형입니다.

let contentHeight = 40
let hasHeader = true
let rowHeight: Int
if hasHeader {
    rowHeight = contentHeight + 50
} else {
    rowHeight = contentHeight + 20
}
// rowHeight 는 90 입니다.

첫 번째 예에서 삼항 조건 연산자를 사용한다는 것은 rowHeight가 한 줄의 코드에서 올바른 값으로 설정 될 수 있음을 의미합니다. 이는 두 번째 예에서 사용 된 코드보다 더 간결합니다.

삼항 조건부 연산자는 고려할 두 표현식을 결정하는 효율적인 속기를 제공합니다. 그러나 삼항 조건 연산자는 주의해서 사용하십시오. 간결함은 과도하게 사용되면 읽기 어려운 코드로 이어질 수 있습니다. 삼항 조건 연산자의 여러 인스턴스를 하나의 복합 명령문으로 결합하지 마십시오.

Nil 병합 연산자 (Nil-Coalescing Operator)

Nil 병합 연산자 (a ?? b)는 값이 포함 된 경우 선택적 a를 래핑 해제하거나 a가 nil 인 경우 기본값 b를 반환합니다. 표현식 a는 항상 옵셔널 타입입니다. 표현식 b는 a 안에 저장된 타입과 일치해야합니다.

nil-병합 연산자는 아래 코드의 축약 형입니다.

a != nil ? a! : b

위의 코드는 삼항 조건 연산자와 강제언래핑 (a!)을 사용하여 a가 nil이 아닌 경우 a 내부에 래핑 된 값에 액세스하고 그렇지 않으면 b를 반환합니다. nil-병합 연산자는이 조건부 검사와 언 래핑을 간결하고 읽기 쉬운 형식으로 캡슐화하는보다 우아한 방법을 제공합니다.

NOTE
a 값이 nil이 아니면 b 값은 평가되지 않습니다. 이를 단락 평가라고합니다.

아래 예제는 nil-병합 연산자를 사용하여 기본 색상 이름과 선택적 사용자 정의 색상 이름 중에서 선택합니다.

let defaultColorName = "red"
var userDefinedColorName: String?   // 기본값 nil

var colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName이 nil이므로 colorNameToUse가 기본값 인 "red"로 설정됩니다.

userDefinedColorName 변수는 기본값이 nil 인 옵셔널 문자열로 정의됩니다. userDefinedColorName은 옵셔널 타입이므로 nil-병합 연산자를 사용하여 값을 고려할 수 있습니다. 위의 예에서 연산자는 colorNameToUse라는 문자열 변수의 초기 값을 결정하는 데 사용됩니다. userDefinedColorName이 nil이므로 userDefinedColorName ?? defaultColorName은 defaultColorName 또는 “red”값을 반환합니다.

userDefinedColorName에 nil이 아닌 값을 할당하고 nil-병합 연산자 검사를 다시 수행하면 기본값 대신 userDefinedColorName 내에 래핑 된 값이 사용됩니다.

userDefinedColorName = "green"
colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName이 nil이 아니므로 colorNameToUse가 "green"으로 설정됩니다.

범위 연산자 (Range Operators)

Swift에는 값의 범위를 표현하는 단축키 인 여러 범위 연산자가 포함되어 있습니다.

@ 폐쇄 범위 연산자(Closed Range Operator)

폐쇄 범위 연산자 (a … b)는 a에서 b까지의 범위를 정의하고 값 a와 b를 포함합니다. a의 값은 b보다 클 수 없습니다.
폐쇄 범위 연산자는 for-in 루프와 같이 모든 값을 사용하려는 범위를 반복 할 때 유용합니다.

for index in 1...5 {
    print("\(index) times 5 is \(index * 5)")
}
// 1 times 5 is 5
// 2 times 5 is 10
// 3 times 5 is 15
// 4 times 5 is 20
// 5 times 5 is 25

@ 반 개방 범위 연산자 (Half-Open Range Operator)

반 개방 범위 연산자 (a..<b)는 a에서 b까지 실행되지만 b는 포함하지 않는 범위를 정의합니다. 첫 번째 값은 포함하지만 최종 값은 포함하지 않기 때문에 반 개방이라고합니다. 폐쇄 범위 연산자와 마찬가지로 a의 값은 b보다 클 수 없습니다. a의 값이 b와 같으면 결과 범위는 비어 있습니다.
반 개방 범위는 배열과 같이 0부터 시작하는 목록으로 작업 할 때 특히 유용합니다. 여기서 목록의 길이까지 세는 것이 유용합니다.

let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
    print("Person \(i + 1) is called \(names[i])")
}
// Person 1 is called Anna
// Person 2 is called Alex
// Person 3 is called Brian
// Person 4 is called Jack

배열에는 4 개의 항목이 포함되어 있지만 0..<count는 반 개방 범위이기 때문에 3 (배열의 마지막 항목의 인덱스)까지만 계산합니다.

@ 단측 범위 (One-Sided Ranges)

닫힌 범위 연산자에는 가능한 한 방향으로 계속되는 범위에 대한 대체 형식이 있습니다. 예를 들어 인덱스 2에서 배열 끝까지 배열의 모든 요소를 포함하는 범위입니다. 이러한 경우 범위 연산자의 한쪽에서 값을 생략 할 수 있습니다. 이러한 종류의 범위는 연산자가 한쪽에만 값이 있기 때문에 단측 범위라고합니다. 예를 들면 :

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[2...] {
    print(name)
}
// Brian
// Jack

for name in names[...2] {
    print(name)
}
// Anna
// Alex
// Brian

반 개방 범위 연산자에는 최종 값만 사용하여 작성된 단측 형식도 있습니다. 양쪽에 값을 포함 할 때와 마찬가지로 최종 값은 범위의 일부가 아닙니다. 예를 들면 :

let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[..<2] {
    print(name)
}
// Anna
// Alex

단측 범위는 첨자뿐만 아니라 다른 컨텍스트에서도 사용할 수 있습니다. 반복이 시작되어야하는 위치가 명확하지 않기 때문에 첫 번째 값을 생략하는 단측 범위에 대해 반복 할 수 없습니다. 최종 값을 생략하는 단측 범위를 반복 할 수 있습니다. 그러나 범위는 무한정 계속되므로 루프에 대한 명시적인 종료 조건을 추가해야합니다. 또한 아래 코드와 같이 단측 범위에 특정 값이 포함되어 있는지 확인할 수 있습니다.

let range = ...5
range.contains(7)   // false
range.contains(4)   // true
range.contains(-1)  // true

논리 연산자 (Logical Operators)

논리 연산자는 부울 논리 값 true 및 false를 수정하거나 결합합니다. Swift는 C 기반 언어에서 볼 수있는 세 가지 표준 논리 연산자를 지원합니다.

  • Logical NOT (!a)
  • Logical AND (a && b)
  • Logical OR (a || b)

@ 논리 NOT 연산자 (Logical NOT Operator)

논리 NOT 연산자 (! a)는 부울 값을 반전하여 true가 false가되고 false가 true가되도록합니다.
논리 NOT 연산자는 접두사 연산자이며 공백없이 작동하는 값 바로 앞에 나타납니다. 다음 예에서와 같이 “not a”로 읽을 수 있습니다.

let allowedEntry = false
if !allowedEntry {
    print("ACCESS DENIED")
}
// Prints "ACCESS DENIED"

if! allowedEntry는 “if not allowed entry”로 읽을 수 있습니다. 다음 줄은 “not allowed entry”가 참인 경우에만 실행됩니다. 즉, allowedEntry가 false 인 경우입니다.
이 예제에서와 같이 부울 상수 및 변수 이름을 신중하게 선택하면 코드를 읽기 쉽고 간결하게 유지하면서 이중 음수 또는 혼동 논리 문을 피할 수 있습니다.

@ 논리 AND 연산자 (Logical AND Operator)

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

두 값 중 하나가 거짓이면 전체 표현식도 거짓이됩니다. 사실 첫 번째 값이 거짓이면 두 번째 값은 평가조차되지 않을 것입니다. 전체 표현식이 참과 같을 수 없기 때문입니다. 이를 단락 평가라고합니다.

이 예에서는 두 개의 Bool 값을 고려하고 두 값이 모두 참인 경우에만 액세스를 허용합니다.

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

@ 논리 OR 연산자 (Logical OR Operator)

논리 OR 연산자 (a || b)는 두 개의 인접한 파이프 문자로 만든 중위 연산자입니다. 전체 표현식이 참이 되려면 두 값 중 하나만 참이어야하는 논리 표현식을 작성하는 데 사용합니다.

위의 논리 AND 연산자와 마찬가지로 논리 OR 연산자는 단락 평가를 사용하여 표현식을 고려합니다. 논리 OR 표현식의 왼쪽이 참이면 전체 표현식의 결과를 변경할 수 없기 때문에 오른쪽이 평가되지 않습니다.

아래 예에서 첫 번째 Bool 값 (hasDoorKey)은 false이지만 두 번째 값 (knowsOverridePassword)은 true입니다. 하나의 값이 true이므로 전체 표현식도 true로 평가되고 액세스가 허용됩니다.

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

@ 논리 결합 연산자 (Combining Logical Operators)

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

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

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

올바른 출입문 코드를 입력하고 망막 스캔을 통과했거나 유효한 출입문 키가 있거나 긴급 재정의 암호를 알고있는 경우 액세스를 허용합니다.

inputDoorCode, passedRetinaScan 및 hasDoorKey의 값에 따라 처음 두 개의 하위 표현식은 false입니다. 그러나 긴급 재정의 암호가 알려져 있으므로 전체 복합 식은 여전히 참으로 평가됩니다.

NOTE
Swift 논리 연산자 && 및 || 왼쪽 연관입니다. 즉, 여러 논리 연산자가있는 복합 표현식은 맨 왼쪽에있는 하위 표현식을 먼저 평가합니다.

명시적 괄호 (Explicit Parentheses)

복잡한 표현의 의도를 더 쉽게 읽을 수 있도록 괄호가 꼭 필요하지 않은 경우 괄호를 포함하는 것이 유용한 경우가 있습니다. 위의 문 액세스 예에서 복합 표현식의 첫 번째 부분 주위에 괄호를 추가하여 의도를 명시하는 것이 유용합니다.

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

괄호는 처음 두 값이 전체 논리에서 개별 가능한 상태의 일부로 간주됨을 명확하게합니다. 복합 표현의 출력은 변경되지 않지만 전체적인 의도는 독자에게 더 명확합니다. 가독성이 항상 간결함보다 선호됩니다. 의도를 명확히하는 데 도움이되는 괄호를 사용하십시오.

에 발행했습니다
SWIFT(으)로 분류되었습니다

aaron님이 작성

아무것도 안해도 시간은 흐른다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다