2018-09-10

기본 연산자

연산자는 특별한 기호 또는 변경 또는 값을 결합하는 데 사용하는 문구입니다. 예를 들어 더하기 연산자(+)는 let i = 1 + 2에서와 같이 두 개의 숫자를 더하고, 논리 AND 연산자 (&&)는 if enteredDoorCode && passedRetinaScan에서와 같이 두 개의 Boolean 값을 결합합니다.

Swift는 대부분의 표준 C 연산자를 지원하며 일반적인 코딩 오류를 제거하는 몇 가지 기능을 향상시킵니다. 대입 연산자(=)는 동등 연산자 (==)가 실수로 사용되지 않도록 값을 반환하지 않습니다. 산술 연산자( +, -, *, /, %등)을 감지하고 이를 저장하는 유형의 허용 값 범위보다 더 크거나 작아 질 수 작업시 예기치 않은 결과를 방지하기 위해 값이 오버 플로우를 허용하지 않습니다. 오버 플로우 연산자에 설명 된대로, 스위프트의 오버 플로우 연산자를 사용하여 값 오버 플로우 동작에 선택할 수 있습니다  .


스위프트는 또한 C에서 발견할 수 없는 범위 연산자 예를 들어  a..<b 그리고 a...b 처럼 값의 범위를 표현하는 손쉬운 방법을 제공합니다.


이 장에서는 스위프트의 일반적인 연산자에 대해 설명합니다. 고급 연산자는 스위프트의 고급 연산자에서 다루며 어떻게 사용자 지정 연산자를 정의하고 사용자 지정 형식에 대한 표준 연산자를 구현하는 방법에 대해 설명합니다.


전문용어

연산자는 단항, 2진또는 3 진 연산자입니다:
  • 단항 연산자는 단일 대상 (예: -a) 에서 작동합니다 . 단항 접두사 연산자는 자신의 대상 직전에 표시(예:  !b) 및 단항 후위 연산자는 자신의 대상 바로 뒤에(예:  c!) 나타납니다.
  • 바이너리 연산자는  두 개의 목표에서 (예: 2 + 3 ) 작동하고,  두 대상의 사이에 나타나기 때문에 삽입자(infix)가 됩니다.
  • 삼항 연산자는 세 가지 대상에서 작동합니다. C와 마찬가지로 스위프트에는 삼항 조건 연산자 (a ? b : c)가 하나만 있습니다.
연산자가 영향을 미치는 값은 피연산자 입니다. 표현식 1 + 2에서 + 기호는 2 항 연산자이고, 두 피연산자는 값 1과 2가 됩니다.


배정 연산자

할당 연산자 (a = b ) 초기화 또는 b의 값을 A값에 갱신하기:

let b = 10

var a = 5
a = b
// a is now equal to 10

만약 할당의 오른쪽이 여러 값을 갖는 튜플 인 경우 해당 요소를 여러 상수 또는 변수로 한 번에 분해 할 수 있습니다:


let (x, y) = (1, 2)

// x is equal to 1, and y is equal to 2

C와 오브젝티브-C의 대입 연산자와 달리 스위프트의 대입 연산자는 그 자체로 값을 반환하지 않습니다. 다음 표현은 유효하지 않습니다.


if x = y {

// This is not valid, because x = y does not return a value.
}

    이 기능은 배정 연산자(=)가 실제로 동등연산자(==)로 의도 된 경우 실수로 사용되는 것을 방지합니다. if x = y를 무효화 함으로써 스위프트는 이러한 종류의 오류를 코드에서 피할 수있게 도와줍니다.

산술 연산자

스위프트는 모든 숫자 유형에 대해 네 가지 표준 산술 연산자 를 지원합니다:
  • 더하기 ( +)
  • 빼기 ( -)
  • 곱하기 ( *)
  • 나누기 ( /)
1 + 2 // equals 3
5 - 3 // equals 2
2 * 3 // equals 6
10.0 / 2.5 // equals 4.0


C 및 오브젝티브-C의 산술 연산자와 달리 스위프트 산술 연산자는 기본적으로 값이 오버플로되지 않도록합니다. 스위프트의 오버플로 연산자(예 : a &+ b)를 사용하여 오버플로 값행위를 선택할 수 있습니다 . 오버플로 연산자를 참조하십시오 .

더하기 연산자는 String연결을 위해서도 지원됩니다:


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



나머지 연산자

나머지 연산자(a % b)는 a에 얼마나 많은 b의 배수와 맞는지 계산하고 남은 값을 반환합니다. (나머지로 알려져 있는 ).
노트
나머지 연산자(%)는 다른 언어의 모듈러 연산자라고도 합니다. 그러나 스위프트에서 음수로 동작한다는 것은 엄밀히 말하자면 모듈러스 연산이 아니라 나머지입니다. 
나머지 연산자는 다음과 같습니다. 9 % 4를 계산하려면 먼저 얼마나 많은 4가 9 내부에 들어갈 수있는 지를 계산 해야합니다.

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

스위프트에서는 다음과 같이 작성됩니다.


9 % 4 // equals 1


a % b에 대한 답을 구하기 위해서는 % 연산자는 다음 방적식을 계산하고 나머지를 외부로 반환합니다.


a= ( b x some multiplier ) + remainder


여기서 일부 배수는 a의 내부에 들어 맞는 b의 배수 중 가장 큰 수입니다.

이 방정식에 9와 4를 삽입하면 다음과 같이됩니다.

a의 음수 값에 대한 나머지를 계산할 때 같은 방법이 적용됩니다.

-9 % 4 // equals -1


-9와 4를 방정식에 대입하면:


-9= ( 4 x -2)  + -1


나머지 값 -1을 준다.


b의 음수 값에 대해서는 b의 부호가 무시됩니다. 즉,  a % b 및 a % -b는 항상 동일한 대답을 제공합니다.



단항 마이너스 연산자

숫자 값의 부호는 단항 마이너스 연산자로 알려진 접두사 -를 사용하여 토글 할 수 있습니다:

let three = 3

let minusThree = -three // minusThree equals -3
let plusThree = -minusThree // plusThree equals 3, or "minus minus three"

단항 마이너스 연산자 (-)는 작업 할 값 앞에 공백없이 직접 추가됩니다.



단항 플러스 연산자

단항 더하기 연산자 (+)는 변경하지 않고 작동하는 값을 반환하기만합니다.

let minusSix = -6

let alsoMinusSix = +minusSix // alsoMinusSix equals -6

단항 더하기 연산자는 실제로 아무 것도하지 않지만 음수에 단항 빼기 연산자를 사용하는 경우 양수에 대한 대칭을 코드에 대칭으로 제공 할 수 있습니다.



복합 할당 연산자

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

var a = 1

a += 2
// a is now equal to 3

a + = 2 표현식은 a = a + 2에 대한 단축입니다. 실제로 추가와 할당은 두 작업을 동시에 수행하는 하나의 연산자로 결합됩니다.
노트 
복합 대입 연산자는 값을 반환하지 않습니다. 예를 들어 let b = a + = 2는 쓸 수 없습니다.

스위프트 표준 라이브러리에서 제공하는 연산자에 대한 자세한 내용은 연산자 선언을 참조하십시오 .


비교 연산자

Swift는 모든 표준 C 비교 연산자를 지원합니다 .
  • 같음  ( a == b )
  • 같지 않음 ( a != b )
  • 보다 큼 ( a > b )
  • 보다 작음 ( a < b )
  • 보다 크거나 같음 ( a >= b )
  • 보다 작거나 같음 ( a <= b )
노트 
스위프트는 두 개의 ID 연산자 (=== 및! ==)도 제공합니다. 두 개의 객체 참조가 모두 동일한 객체 인스턴스를 참조하는지 여부를 테스트하는 데 사용합니다. 자세한 내용은 구조 및 클래스를 참조하십시오.

각 비교 연산자는 Bool 값을 반환하여 조건문이 true인지 여부를 나타냅니다.


1 == 1 // true because 1 is equal to 1

2 != 1 // true because 2 is not equal to 1
2 > 1 // true because 2 is greater than 1
1 < 2 // true because 1 is less than 2
1 >= 1 // true because 1 is greater than or equal to 1
2 <= 1 // false because 2 is not less than or equal to 1

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

let name = "world"

if name == "world" {
print("hello, world")
} else {
print("I'm sorry \(name), but I don't recognize you")
}
// Prints "hello, world", because name is indeed equal to "world".

if명령문에 대한 자세한 내용은 제어 흐름을 참조하십시오 .


두 튜플의 유형과 개수가 같은 튜플을 비교할 수 있습니다. 튜플은 왼쪽에서 오른쪽으로 한 번에 하나의 값만큼 비교되어 비교가 두 값이 같지 않을 때까지 비교됩니다. 이 두 값이 비교되고 그 비교 결과가 튜플 비교의 전체 결과를 결정합니다. 모든 요소가 같으면 튜플 자체가 동일합니다. 예 :


(1, "zebra") < (2, "apple") // true because 1 is less than 2; "zebra" and "apple" are not 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"

위의 예제에서 첫 번째 행에서 왼쪽에서 오른쪽으로 비교하는 동작을 볼 수 있습니다. 1이 2보다 작으므로 튜플의 다른 값과 관계없이 (1, "zebra")은 (2, "apple")보다 작은 것으로 간주됩니다. 비교가 이미 튜플의 첫 번째 요소에 의해 결정되므로 "zebra"이 "apple"보다 작지는 않습니다. 그러나 튜플의 첫 번째 요소가 동일 할 때 두 번째 요소가 비교됩니다. 두 번째 및 세 번째 행에서 발생합니다.


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


("blue", -1) < ("purple", 1) // OK, evaluates to true

("blue", false) < ("purple", true) // Error because < can't compare Boolean values
노트스위프트 표준 라이브러리에는 7 개 미만의 요소가있는 튜플에 대한 튜플 비교 연산자가 포함되어 있습니다. 튜플과 7 개 이상의 요소를 비교하려면 비교 연산자를 직접 구현해야합니다.


삼항 조건 연산자

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

삼항 조건부 연산자는 아래 코드에서 생략 할 수 있습니다.


if question {

answer1
} else {
answer2
}

다음은 테이블 행의 높이를 계산하는 예제입니다. 행 높이가 콘텐츠 높이보다 50 포인트 높고 행에 헤더가있는 경우 높이가 커야하며 행에 헤더가없는 경우 높이가 20 포인트가되어야합니다.

let contentHeight = 40

let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight is equal to 90

위의 예는 아래 코드를 요약 한 것입니다.


let contentHeight = 40

let hasHeader = true
let rowHeight: Int
if hasHeader {
rowHeight = contentHeight + 50
} else {
rowHeight = contentHeight + 20
}
// rowHeight is equal to 90

첫 번째 예제에서 삼항 조건부 연산자를 사용하면 rowHeight를 한 줄의 코드에서 올바른 값으로 설정할 수 있습니다. 두 번째 예제에서 사용 된 코드보다 간결합니다.


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



Nil 병합 연산자

nil-coalescing 연산자 (a ?? b)는 선택적인 a가 값을 포함하고 있으면 랩핑 해제하고, a가 0이면 디폴트 값 b를 리턴합니다. 표현식 a는 항상 선택적 유형입니다. 표현식 b는 a에 저장된 유형과 일치해야합니다.

nil-coalescing 연산자는 아래 코드에서 생략 할 수 있습니다.


a != nil ? a! : b


위의 코드는 삼항 조건 연산자와 강제적 인 언 래핑 (a!)을 사용하여 a가 nil이 아닐 때 wrapped 된 값에 액세스하고, 그렇지 않으면 b를 반환합니다. nil-coalescing 연산자는이 조건부 검사와 언 래핑을 간결하고 읽기 쉬운 형식으로 캡슐화하는보다 우아한 방법을 제공합니다.
노트 
a의 값이 nil이 아닌 경우 b의 값은 평가되지 않습니다. 이것을 단락 평가라고합니다.

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

let defaultColorName = "red"

var userDefinedColorName: String? // defaults to nil

var colorNameToUse = userDefinedColorName ?? defaultColorName

// userDefinedColorName is nil, so colorNameToUse is set to the default of "red"

userDefinedColorName 변수는 선택적인 String으로 정의되며 기본값은 nil입니다. userDefinedColorName은 선택적 유형이므로 nil-coalescing 연산자를 사용하여 해당 값을 고려할 수 있습니다. 위의 예에서 연산자는 colorNameToUse라는 String 변수의 초기 값을 결정하는 데 사용됩니다. userDefinedColorName이 nil이므로 표현식 userDefinedColorName ?? defaultColorName은 defaultColorName 또는 "red"값을 반환합니다.


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


userDefinedColorName = "green"

colorNameToUse = userDefinedColorName ?? defaultColorName
// userDefinedColorName is not nil, so colorNameToUse is set to "green"

범위 연산자

스위프트에는 범위의 값을 표현하기위한 바로 가기 인 여러 범위 연산자가 포함되어 있습니다.

닫힌 범위 연산자

닫힌 범위 연산자 (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

for- in루프 에 대한 자세한 내용 은 흐름제어를 참조하십시오 .



반 개방 범위 연산자

반 개방 범위 연산자 (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까지 계산됩니다. 배열에 대한 자세한 내용은 배열을 참조하십시오.



일방적 인 범위

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

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


논리 연산자

논리 연산자는 부울 논리 값 true 및 false를 수정하거나 결합합니다. Swift는 C 기반 언어에서 발견되는 세 가지 표준 논리 연산자를 지원합니다.
  • 논리적 NOT ( !a)
  • 논리 AND ( )a && b
  • 논리 OR ( )a || b

논리 NOT 연산자

논리적 NOT 연산자 (! a)는 부울 값을 반전하여 true가 false가되고 false가 true가됩니다.

논리적 NOT 연산자는 접두사 연산자이며 작업 할 값 바로 앞에 공백없이 나타납니다. 다음 예제에서와 같이 "not a"로 읽을 수 있습니다.


let allowedEntry = false

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

if! allowedEntry 구문은 "허용되지 않는 항목"으로 읽을 수 있습니다. "허용되지 않는 항목"이 참이면 후속 행만 실행됩니다. 즉, allowedEntry가 false 인 경우


이 예제에서와 같이 부울 상수 및 변수 이름을주의 깊게 선택하면 코드가 읽기 쉽고 간결하게 유지되며 이중 부정 또는 혼동 논리 문을 피할 수 있습니다.



논리 AND 연산자

논리적 AND 연산자 (a && b)는 논리적 표현식을 작성합니다. 논리적 표현식은 전체 표현식이 참이되도록하려면 두 값이 모두 참이어야합니다.

두 값 중 하나가 거짓이면 전체 식도 거짓입니다. 사실, 첫 번째 값이 false이면 두 번째 값도 계산되지 않습니다. 왜냐하면 전체 표현식을 true로 설정할 수 없기 때문입니다. 이것을 단락 평가라고합니다.


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


let enteredDoorCode = true

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


논리 OR 연산자

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

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


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


let hasDoorKey = false

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


논리 연산자 결합

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

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {

print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"

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


올바른 문 코드를 입력하고 망막 스캔을 통과했거나 유효한 출입문 키가 있거나 비상용 무시 암호를 알고있는 경우 액세스를 허용하십시오.


enteredDoorCode, passedRetinaScan 및 hasDoorKey의 값에 따라 처음 두 개의 하위 표현식은 false입니다. 그러나 비상 재정의 암호는 알고 있으므로 전체 복합 표현은 여전히 true로 평가됩니다.

노트 
Swift 논리 연산자 && 및 || 는 왼쪽 연관입니다. 즉, 여러 논리 연산자를 사용하는 복합 표현식이 가장 왼쪽 부 표현식을 먼저 평가합니다.

명시 적 괄호

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

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {

print("Welcome!")
} else {
print("ACCESS DENIED")
}
// Prints "Welcome!"

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


<- 돌아가기

댓글 없음:

댓글 쓰기