Basic Operators Swift


Basic Operators

연산자는 특별한 심볼 또는 표현식으로서 값을 체크, 변경, 결합할 때 사용한다. 예를 들어, + 연산자는 두 값을 더하며 && 는 두 불린 값을 결합한다. 

스위프트는 대부분의 표준 C연산자를 지원하며 몇가지의 호환성을 향상시키며, 공통의 코딩 에러를 제거한다. 할당 연산은 결과를 반환하지 않는데, == 연산자가 나타내는 것으로 부터 실수로 사용되지 않기 위해서다. Arithmetic operators (+, -, *, /, % and so forth) detect and disallow value overflow, to avoid unexpected results when working with numbers that become larger or smaller than the allowed value range of the type that stores them. You can opt in to value overflow behavior by using Swift’s overflow operators, as described in Overflow Operators.

스위프트는 C에서는 없는 범위 연산자도 지원하는데 a..<b a...b 와 같은 것이다.

This chapter describes the common operators in Swift. Advanced Operators covers Swift’s advanced operators, and describes how to define your own custom operators and implement the standard operators for your own custom types.

용어

연산자는 단항, 이항, 다항 이 있다.

Unary operators operate on a single target (such as -a). Unary prefix operators appear immediately before their target (such as !b), and unary postfix operators appear immediately after their target (such as c!).

Binary operators operate on two targets (such as 2 + 3) and are infix because they appear in between their two targets.

Ternary operators operate on three targets. Like C, Swift has only one ternary operator, the ternary conditional operator (a ? b : c).

The values that operators affect are operands. In the expression 1 + 2, the + symbol is a binary operator and its two operands are the values 1 and 2.

할당 연산자

The assignment operator (a = b) initializes or updates the value of a with the value of b:

let b = 10
var a = 5
a = b

할당의 오른쪽 부분이 다중값의 튜플이면 이 요소는 다중의 상수나 변수로 한번에 분해될 수 있다.

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

C와 오브젝티브C에서의 할당연산자와 달리, 스위프트의 할당연산자는 값을 반환하지 않는다. 다음은 무효하다.

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

이 기능은 실수에 의해 =이 쓰여지지 않기 위해서다. By making if x = y invalid, Swift helps you to avoid these kinds of errors in your code.


수치연산자

Swift supports the four standard arithmetic operators for all number types:

Addition (+)
Subtraction (-)
Multiplication (*)
Division (/)
1 + 2       // equals 3
5 - 3       // equals 2
2 * 3       // equals 6
10.0 / 2.5  // equals 4.0

C와 오브젝티브C와 달리 스위프트는 기본적으로 오버플로우를 허용하지 않는다. a &+ b와 같은 스위프트 오버플로우 연산을 사용하여 값오버플로우를 수행할 수 있다. See Overflow Operators.

The addition operator is also supported for String concatenation:

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

리마인더 연산자

The remainder operator (a % b) works out how many multiples of b will fit inside a and returns the value that is left over (known as the remainder).

NOTE

The remainder operator (%) is also known as a modulo operator in other languages. However, its behavior in Swift for negative numbers means that, strictly speaking, it’s a remainder rather than a modulo operation.

Here’s how the remainder operator works. To calculate 9 % 4, you first work out how many 4s will fit inside 9:

../_images/remainderInteger_2x.png


You can fit two 4s inside 9, and the remainder is 1 (shown in orange).

In Swift, this would be written as:

9 % 4    // equals 1
To determine the answer for a % b, the % operator calculates the following equation and returns remainder as its output:

a = (b x some multiplier) + remainder

where some multiplier is the largest number of multiples of b that will fit inside a.

Inserting 9 and 4 into this equation yields:

9 = (4 x 2) + 1

The same method is applied when calculating the remainder for a negative value of a:

-9 % 4   // equals -1
Inserting -9 and 4 into the equation yields:

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

giving a remainder value of -1.

The sign of b is ignored for negative values of b. This means that a % b and a % -b always give the same answer.

단항 마이너스 연산자

The sign of a numeric value can be toggled using a prefixed -, known as the unary minus operator:

let three = 3
let minusThree = -three       // minusThree equals -3
let plusThree = -minusThree   // plusThree equals 3, or "minus minus three"
The unary minus operator (-) is prepended directly before the value it operates on, without any white space.

단항 플러스 연산자

The unary plus operator (+) simply returns the value it operates on, without any change:

let minusSix = -6
let alsoMinusSix = +minusSix  // alsoMinusSix equals -6
Although the unary plus operator doesn’t actually do anything, you can use it to provide symmetry in your code for positive numbers when also using the unary minus operator for negative numbers.

복합 할당 연산자

Like C, Swift provides compound assignment operators that combine assignment (=) with another operation. One example is the addition assignment operator (+=):

var a = 1
a += 2
// a is now equal to 3
The expression a += 2 is shorthand for a = a + 2. Effectively, the addition and the assignment are combined into one operator that performs both tasks at the same time.

NOTE

The compound assignment operators don’t return a value. For example, you can’t write let b = a += 2.

For information about the operators provided by the Swift standard library, see Operator Declarations.

비교 연산자

Swift supports all standard C comparison operators:

Equal to (a == b)
Not equal to (a != b)
Greater than (a > b)
Less than (a < b)
Greater than or equal to (a >= b)
Less than or equal to (a <= b)
NOTE

Swift also provides two identity operators (=== and !==), which you use to test whether two object references both refer to the same object instance. For more information, see Structures and Classes.

Each of the comparison operators returns a Bool value to indicate whether or not the statement is 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
Comparison operators are often used in conditional statements, such as the if statement:

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".
For more about the if statement, see Control Flow.

만약 같은 형식에 값의 갯수가 같으면 튜플도 비교할 수 있다. 튜플은 왼쪽에서 오른쪽으로 한번에 하나씩 같지 않은 두 값을 찾을 때까지 비교를 계속한다. 이들 두 값이 비교되면 결과는 튜플 비교의 전체 결과가 된다. 만약 모든 요소가 같으면 튜플은 같다고 한다. 예를들어

(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"

In the example above, you can see the left-to-right comparison behavior on the first line. Because 1 is less than 2, (1, "zebra") is considered less than (2, "apple"), regardless of any other values in the tuples. It doesn’t matter that "zebra" isn’t less than "apple", because the comparison is already determined by the tuples’ first elements. However, when the tuples’ first elements are the same, their second elements are compared—this is what happens on the second and third line.

튜플은 각 값에 해당 연산자를 적용할 수 있을 때 비교를 수행한다. For example, as demonstrated in the code below, you can compare two tuples of type (String, Int) because both String and Int values can be compared using the < operator. 대조적으로, 튜플의 값이 (String, Bool) 이면 < 연산자로는 비교할 수 없다.

("blue", -1) < ("purple", 1)        // OK, evaluates to true
("blue", false) < ("purple", true)  // Error because < can't compare Boolean values

일러두기)
The Swift standard library includes tuple comparison operators for tuples with fewer than seven elements. To compare tuples with seven or more elements, you must implement the comparison operators yourself.

삼항 조건 연산자

삼항 조건연산자는 세 부분으로 구성된 특별한 연산자로서 question ? answer1 : answer2 이다. It’s a shortcut for evaluating one of two expressions based on whether question is true or false. If question is true, it evaluates answer1 and returns its value; otherwise, it evaluates answer2 and returns its value.

The ternary conditional operator is shorthand for the code below:

if question {
    answer1
} else {
    answer2
}

Here’s an example, which calculates the height for a table row. The row height should be 50 points taller than the content height if the row has a header, and 20 points taller if the row doesn’t have a header:

let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
// rowHeight is equal to 90
The example above is shorthand for the code below:

let contentHeight = 40
let hasHeader = true
let rowHeight: Int
if hasHeader {
    rowHeight = contentHeight + 50
} else {
    rowHeight = contentHeight + 20
}
// rowHeight is equal to 90
The first example’s use of the ternary conditional operator means that rowHeight can be set to the correct value on a single line of code, which is more concise than the code used in the second example.

The ternary conditional operator provides an efficient shorthand for deciding which of two expressions to consider. Use the ternary conditional operator with care, however. Its conciseness can lead to hard-to-read code if overused. Avoid combining multiple instances of the ternary conditional operator into one compound statement.

닐-연계 연산자

닐 연계 연산자인 (a ?? b) 는 옵셔널 a가 값을 가지면 언랩하고 닐이면 기본값인 b를 반환한다. 표현 a는 항상 옵셔널 형식이어야 한다. 표현 b는 항상 a가 가진 형식과 동일해야 한다.

닐연계 연산자는 다음과 같이 표현될 수 있다.

a != nil ? a! : b

The code above uses the ternary conditional operator and forced unwrapping (a!) to access the value wrapped inside a when a is not nil, and to return b otherwise. The nil-coalescing operator provides a more elegant way to encapsulate this conditional checking and unwrapping in a concise and readable form.

일러두기)
만약 a가 닐이 아니면 값 b는 실행되지 않는다. 이 것을 숏서킷 실행이라 한다.

The example below uses the nil-coalescing operator to choose between a default color name and an optional user-defined color name:

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"
The userDefinedColorName variable is defined as an optional String, with a default value of nil. Because userDefinedColorName is of an optional type, you can use the nil-coalescing operator to consider its value. In the example above, the operator is used to determine an initial value for a String variable called colorNameToUse. Because userDefinedColorName is nil, the expression userDefinedColorName ?? defaultColorName returns the value of defaultColorName, or "red".

If you assign a non-nil value to userDefinedColorName and perform the nil-coalescing operator check again, the value wrapped inside userDefinedColorName is used instead of the default:

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

범위 연산자

스위프트는 일부 범위 연산자를 포함하며 이는 값의 범위를 표현하기 위한 지름길이다.

닫힌 범위 연산자

The closed range operator (a...b) defines a range that runs from a to b, and includes the values a and b. The value of a must not be greater than b.

The closed range operator is useful when iterating over a range in which you want all of the values to be used, such as with a for-in loop:

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 more about for-in loops, see Control Flow.

반열림 범위 연산자

The half-open range operator (a..<b) defines a range that runs from a to b, but doesn’t include b. It’s said to be half-open because it contains its first value, but not its final value. As with the closed range operator, the value of a must not be greater than b. If the value of a is equal to b, then the resulting range will be empty.

Half-open ranges are particularly useful when you work with zero-based lists such as arrays, where it’s useful to count up to (but not including) the length of the list:

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
Note that the array contains four items, but 0..<count only counts as far as 3 (the index of the last item in the array), because it’s a half-open range. For more about arrays, see Arrays.

원사이드 범위

닫힌 범위 연산자로서 범위의 대체 폼으로서 한 방향으로 최대한 멀리 계속하는 것이다. 예를 들어 범위가 인덱스 2부터 인덱스의 끝까지라면 범위 연산에서 한 부분을 생략할 수 있다. 이런 종류의 범위를 원사이드 범위라고하는데 한 사이드에만 값이 있기 때문이다. 예를 들어,

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

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

The half-open range operator also has a one-sided form that’s written with only its final value. Just like when you include a value on both sides, the final value isn’t part of the range. For example:

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 modify or combine the Boolean logic values true and false. Swift supports the three standard logical operators found in C-based languages:

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

논리 NOT 연산자

The logical NOT operator (!a) inverts a Boolean value so that true becomes false, and false becomes true.

The logical NOT operator is a prefix operator, and appears immediately before the value it operates on, without any white space. It can be read as “not a”, as seen in the following example:

let allowedEntry = false
if !allowedEntry {
    print("ACCESS DENIED")
}
// Prints "ACCESS DENIED"
The phrase if !allowedEntry can be read as “if not allowed entry.” The subsequent line is only executed if “not allowed entry” is true; that is, if allowedEntry is false.

As in this example, careful choice of Boolean constant and variable names can help to keep code readable and concise, while avoiding double negatives or confusing logic statements.

논리 AND 연산자

The logical AND operator (a && b) creates logical expressions where both values must be true for the overall expression to also be true.

If either value is false, the overall expression will also be false. In fact, if the first value is false, the second value won’t even be evaluated, because it can’t possibly make the overall expression equate to true. This is known as short-circuit evaluation.

This example considers two Bool values and only allows access if both values are true:

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

논리 OR 연산자

The logical OR operator (a || b) is an infix operator made from two adjacent pipe characters. You use it to create logical expressions in which only one of the two values has to be true for the overall expression to be true.

Like the Logical AND operator above, the Logical OR operator uses short-circuit evaluation to consider its expressions. If the left side of a Logical OR expression is true, the right side is not evaluated, because it can’t change the outcome of the overall expression.

In the example below, the first Bool value (hasDoorKey) is false, but the second value (knowsOverridePassword) is true. Because one value is true, the overall expression also evaluates to true, and access is allowed:

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

논리 연산자 결합하기

You can combine multiple logical operators to create longer compound expressions:

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
This example uses multiple && and || operators to create a longer compound expression. However, the && and || operators still operate on only two values, so this is actually three smaller expressions chained together. The example can be read as:

If we’ve entered the correct door code and passed the retina scan, or if we have a valid door key, or if we know the emergency override password, then allow access.

Based on the values of enteredDoorCode, passedRetinaScan, and hasDoorKey, the first two subexpressions are false. However, the emergency override password is known, so the overall compound expression still evaluates to true.

NOTE

The Swift logical operators && and || are left-associative, meaning that compound expressions with multiple logical operators evaluate the leftmost subexpression first.

명시적 괄호

It’s sometimes useful to include parentheses when they’re not strictly needed, to make the intention of a complex expression easier to read. In the door access example above, it’s useful to add parentheses around the first part of the compound expression to make its intent explicit:

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
    print("Welcome!")
} else {
    print("ACCESS DENIED")
}
// Prints "Welcome!"
The parentheses make it clear that the first two values are considered as part of a separate possible state in the overall logic. The output of the compound expression doesn’t change, but the overall intention is clearer to the reader. Readability is always preferred over brevity; use parentheses where they help to make your intentions clear.


덧글

댓글 입력 영역