Swift Language
고급 연산자
수색…
사용자 지정 연산자
Swift는 사용자 지정 연산자 생성을 지원합니다. 새로운 연산자는 operator
키워드를 사용하여 전역 수준에서 선언됩니다.
연산자의 구조는 피연산자 배치, 우선 순위 및 연관성의 세 부분으로 정의됩니다.
prefix
,infix
및postfix
수정자는 사용자 정의 연산자 선언을 시작하는 데 사용됩니다.prefix
와postfix
수정자는 연산자가 작동하는 값의 전후에 있어야하는지 여부를 선언합니다. 이러한 연산자는 하나의 대상에서만 작동 할 수 있으므로8
및3++
** 와 같은 urnary입니다.infix
2+3
과 같이 두 값 사이에서 작동하는 2 항 연산자를 선언합니다.우선 순위 가 더 높은 연산자가 먼저 계산됩니다. 기본 연산자 우선 순위는
?
보다 높습니다?
...:
(Swift 2.x에서 100의 값). 표준 Swift 운영자의 우선 순위는 여기에서 확인할 수 있습니다.연관성 은 우선 순위가 같은 연산자 간의 연산 순서를 정의합니다. 왼쪽 연관 연산자는 왼쪽에서 오른쪽으로 (대부분의 연산자와 마찬가지로 읽기 순서) 계산되며, 오른쪽 연관 연산자는 오른쪽에서 왼쪽으로 계산됩니다.
Swift 3.0부터는 연산자 자체 대신 우선 순위 그룹 에서 우선 순위와 연관성을 정의하므로 여러 연산자가 암묵적인 숫자를 참조하지 않고 쉽게 동일한 우선 순위를 공유 할 수 있습니다. 표준 우선 순위 그룹 목록은 아래와 같습니다 .
연산자는 계산 코드를 기반으로 값을 반환합니다. 이 코드는 입력 형식을 지정하는 매개 변수와 연산자가 반환하는 계산 된 값을 지정하는 return
키워드를 사용하여 일반 함수로 작동합니다.
표준 Swift에는 지수 연산자가 없기 때문에 간단한 지수 연산자를 정의합니다.
import Foundation
infix operator ** { associativity left precedence 170 }
func ** (num: Double, power: Double) -> Double{
return pow(num, power)
}
infix
는 **
연산자가 9**2
와 같은 두 값 사이에서 작동 함을 나타냅니다. 이 함수는 연관성을 잃었으므로 3**3**2
는 (3**3)**2
로 계산됩니다. 의 우선 순위 170
즉, 모든 표준 신속한 동작보다 높은 3+2**4
로 계산한다 19
의 왼쪽 연관성 불구 **
.
import Foundation
infix operator **: BitwiseShiftPrecedence
func ** (num: Double, power: Double) -> Double {
return pow(num, power)
}
우선 순위와 연관성을 명시 적으로 지정하는 대신 Swift 3.0에서 올바른 값을 제공하는 기본 우선 순위 그룹 BitwiseShiftPrecedence를 사용할 수 있습니다 ( <<
, >>
와 동일).
** : 증가 및 감소는 더 이상 사용되지 않으며 스위프트 3에서 제거됩니다.
사전에 오버로딩 +
현재 Swift에서 사전을 결합하는 간단한 방법은 없으므로 generics를 사용하여이 기능을 추가하려면 +
및 +=
연산자를 오버로드 하는 것이 유용 할 수 있습니다.
// Combines two dictionaries together. If both dictionaries contain
// the same key, the value of the right hand side dictionary is used.
func +<K, V>(lhs: [K : V], rhs: [K : V]) -> [K : V] {
var combined = lhs
for (key, value) in rhs {
combined[key] = value
}
return combined
}
// The mutable variant of the + overload, allowing a dictionary
// to be appended to 'in-place'.
func +=<K, V>(inout lhs: [K : V], rhs: [K : V]) {
for (key, value) in rhs {
lhs[key] = value
}
}
Swift 3에서, inout
은 인수 유형 앞에 놓여 야합니다.
func +=<K, V>(lhs: inout [K : V], rhs: [K : V]) { ... }
사용 예 :
let firstDict = ["hello" : "world"]
let secondDict = ["world" : "hello"]
var thirdDict = firstDict + secondDict // ["hello": "world", "world": "hello"]
thirdDict += ["hello":"bar", "baz":"qux"] // ["hello": "bar", "baz": "qux", "world": "hello"]
교환 연산자
CGSize를 곱하는 커스텀 연산자를 추가해 봅시다.
func *(lhs: CGFloat, rhs: CGSize) -> CGSize{
let height = lhs*rhs.height
let width = lhs*rhs.width
return CGSize(width: width, height: height)
}
지금이 작품
let sizeA = CGSize(height:100, width:200)
let sizeB = 1.1 * sizeA //=> (height: 110, width: 220)
그러나 작업을 역으로 수행하려고하면 오류가 발생합니다.
let sizeC = sizeB * 20 // ERROR
그러나 다음과 같이 간단하게 추가 할 수 있습니다.
func *(lhs: CGSize, rhs: CGFloat) -> CGSize{
return rhs*lhs
}
이제 연산자는 교환 가능합니다.
let sizeA = CGSize(height:100, width:200)
let sizeB = sizeA * 1.1 //=> (height: 110, width: 220)
비트 연산자
Swift Bitwise 연산자를 사용하면 이진 형식의 숫자에 대한 연산을 수행 할 수 있습니다. 사용자는 해당 번호 앞에 붙어 진 문자를 지정할 수 0b
예 있도록 0b110
이진수 110 (십진수 6)에 상당한다. 각 1 또는 0은 숫자의 비트입니다.
비트 NOT ~
:
var number: UInt8 = 0b01101100
let newNumber = ~number
// newNumber is equal to 0b01101100
여기에서 각 비트는 그 반대로 변경됩니다. 명시 적으로 숫자를 선언하면 UInt8
은 숫자가 양수임을 확인하므로 (예제에서 네거티브를 처리 할 필요가 없도록) 8 비트라고 가정합니다. 0b01101100
이 더 큰 UInt 인 경우 1로 변환되고 역변환 할 때 중요 해지는 선행 0이 있습니다.
var number: UInt16 = 0b01101100
// number equals 0b0000000001101100
// the 0s are not significant
let newNumber = ~number
// newNumber equals 0b1111111110010011
// the 1s are now significant
- 0 -> 1
- 1 -> 0
비트 AND &
:
var number = 0b0110
let newNumber = number & 0b1010
// newNumber is equal to 0b0010
여기서 &
연산자 양쪽의 이진수가 해당 비트 위치에 1을 포함하는 경우에만 주어진 비트가 1이됩니다.
- 0 & 0 -> 0
- 0 & 1 -> 0
- 1 & 1 -> 1
비트 OR |
:
var number = 0b0110
let newNumber = number | 0b1000
// newNumber is equal to 0b1110
여기, 주어진 비트가 1이 될 것이다 경우에만 경우의 적어도 한면의 진수 |
운영자는 해당 비트 위치에 1을 포함했습니다.
- 0 | 0 -> 0
- 0 | 1 -> 1
- 1 | 1 -> 1
비트 XOR (배타적 OR) ^
:
var number = 0b0110
let newNumber = number ^ 0b1010
// newNumber is equal to 0b1100
여기서 두 피연산자의 해당 위치에있는 비트가 다른 경우에만 주어진 비트가 1이됩니다.
- 0 ^ 0 -> 0
- 0 ^ 1 -> 1
- 1 ^ 1 -> 0
모든 2 진 조작의 경우, 피연산자의 순서는 결과에 차이를주지 않습니다.
오버플로 연산자
오버플로는 작업에서 지정된 수의 비트 수보다 크거나 작은 수의 결과가 발생할 때 발생하는 상황을 나타냅니다.
이진 산술이 작동하는 방식 때문에 숫자가 비트에 비해 너무 커지면 그 숫자는 가능한 한 가장 작은 숫자 (비트 크기의 경우)로 오버플로 된 다음 거기에서 계속해서 카운트 업을 계속합니다. 마찬가지로, 숫자가 너무 작아지면, 가능한 최대 수 (비트 크기에 대해)까지 언더 플로우하고 거기에서부터 계속해서 카운트 다운합니다.
이 동작은 자주 필요하지 않으며 심각한 보안 문제가 발생할 수 있으므로 Swift 산술 연산자 인 +
, -
및 *
는 연산이 오버플로 또는 언더 플로를 일으킬 때 오류를 발생시킵니다. 명시 적으로 오버플로 및 언더 플로를 허용하려면 &+
, &-
및 &*
사용하십시오.
var almostTooLarge = Int.max
almostTooLarge + 1 // not allowed
almostTooLarge &+ 1 // allowed, but result will be the value of Int.min
표준 스위프트 운영자의 우선 순위
더 엄격한 (우선 순위가 높은) 연산자가 먼저 나열됩니다.
연산자 | 우선 순위 그룹 (≥3.0) | 상위 | 연관성 |
---|---|---|---|
. | ∞ | 왼쪽 | |
? , ! , ++ , -- , [] , () , {} | (후위) | ||
! , ~ , + , - , ++ , -- | (접두사) | ||
~> (신속한 ≤2.3) | 255 자 | 왼쪽 | |
<< , >> | BitwiseShiftPrecedence | 160 | 없음 |
* , / , % , & , &* | MultiplicationPrecedence | 150 | 왼쪽 |
+ , - , | , ^ , &+ , &- | AdditionPrecedence | 140 | 왼쪽 |
... , ..< | RangeFormationPrecedence | 135 | 없음 |
is , as , as? , as! | CastingPrecedence | 132 | 왼쪽 |
?? | NilCoalescingPrecedence | 131 | 권리 |
< , <= , > , >= , == === != , === !== , ~= | 비교 우위 | 130 | 없음 |
&& | LogicalConjunctionPrecedence | 120 | 왼쪽 |
|| | LogicalDisjunctionPrecedence | 110 | 왼쪽 |
DefaultPrecedence * | 없음 | ||
? ... : | TernaryPrecedence | 100 | 권리 |
= , += , -= , *= , /= , %= , <<= , >>= , &= , |= , ^= | 배정 된 권한 | 90 | 권리, 임무 |
-> | FunctionArrowPrecedence | 권리 |
-
DefaultPrecedence
우선 순위 그룹은TernaryPrecedence
보다TernaryPrecedence
나머지 연산자와 순서가 없습니다. 이 그룹 이외의 다른 우선 순위는 선형입니다.
- 이 표는 Apple의 API 참조 서 에서도 찾을 수 있습니다.
- 우선 순위 그룹의 실제 정의는 GitHub의 소스 코드에서 찾을 수 있습니다.