Swift Advanced Operators
Define custom operators, perform bitwise operations, and use builder syntax.
1. Advanced Operators π©βπ»
Swift λ C
λ Objective-C
μ μ μ¬ν Bitwise Operators
λ₯Ό ν¬ν¨ν΄ μ¬λ¬ κ³ κΈ μ°μ°μλ₯Ό μ 곡νλ€. Swift λ
C μ Arithmetic Operators μ λ¬λ¦¬ κΈ°λ³Έμ μΌλ‘ Overflow λμ§ μλλ€.
Overflow λ trapped
λμ΄ μλ¬λ‘ λ³΄κ³ λλ€.
Swift μμ Overflow νλμ νλλ‘ νλ €λ©΄ Overflow Addition Operator($+)
μ κ°μ μ°μ°μλ₯Ό μ¬μ©ν΄μΌνλ€
(λͺ¨λ Overflow Operators
λ &
λ‘ μμνλ€).
Custom Classes, Structures, Enumerations λ₯Ό μ μν λ, Custom Types μ λν΄ Standard Swift Operators μ ꡬνμ μ 곡νλ κ²μ΄ μ μ©ν μ μλ€. Swift λ Custom Types μ λν΄ Custom Operators λ₯Ό μμ½κ² μ 곡ν μ μλλ‘ νλ©°, κ° Types μ λν νλμ΄ μ νν 무μμΈμ§ κ²°μ ν μ μλ€.
Custom Operators λ μ¬μ μ μ μλ Operators λ‘ μ νλμ§ μμΌλ©°, Swift λ μμ λ§μ Infix
, Prefix
,
Assignment Operators
λ₯Ό μ μν¨μ λ¬Όλ‘ , μμ λ§μ μ°μ μμ
λ₯Ό μμ λ‘κ² μ μν μ μλ€. μ΄λ¬ν Custom Operators
λ μ½λμμ Swift κ° κΈ°λ³Έμ μΌλ‘ μ 곡νλ Predefined Operators
μ²λΌ μ¬μ©λλ©°, Custom Operators λ₯Ό μ±ννλλ‘
κΈ°μ‘΄μ Types λ₯Ό νμ₯ν μ μλ€.
2. Bitwise Operators π©βπ»
1. Bitwise Operators
Bitwise Operators λ Data Structure λ΄μμ κ°λ³ Raw Bits
λ₯Ό μ‘°μν μ μκ² ν΄μ€λ€. μ΄κ²μ Graphics
Programming μ΄λ λλ°μ΄μ€ λλΌμ΄λ² μμ± κ°μ Low-Level Programming μμ μ£Όλ‘ μ¬μ©λλ€. λν μΈλΆ μμ€λ‘λΆν°
Custom Protocol μ μ¬μ©ν΄ ν΅μ νλ λ°μ΄ν° Encoding/Decoding μμ
μ μ¬μ©νκΈ°λ νλ€. Swift λ C κ°
κ°κ³ μλ λͺ¨λ Bitwise Operators λ₯Ό μ§μνλ€.
func printToBinary(number: UInt8) {
print(toBinary(number))
func toBinary(_ number: UInt8) -> String {
let binary = String(number, radix: 2)
if binary.count < number.bitWidth {
return String(repeating: "0", count: 8 - binary.count) + binary
} else {
return binary
}
}
}
μ ν¨μλ₯Ό λ§λ€κ³ λΉνΈ μ°μ° κ²°κ³Όλ₯Ό νμΈν΄λ³΄μ.
2. Bitwise NOT Operator ~
Bitwise NOT Operator ~
λ Prefix Operator
λ‘ κ³΅λ°± μμ΄
κ° λ°λ‘ μμ μμΉν΄ μ«μμ λͺ¨λ λΉνΈλ₯Ό λ°μ μν¨λ€.
let initialBits: UInt8 = 0b00001111
let invertedBits = ~initialBits
printToBinary(number: invertedBits) // 11110000
UInt8
μ μλ 8λΉνΈλ₯Ό κ°μ§λ©° 0 ~ 255 μ¬μ΄μ μ«μλ₯Ό μ μ₯ν μ μμΌλ©°, 2μ§μ 00001111
λ‘ μ΄λ£¨μ΄μ§ 8λΉνΈ λ°μ΄ν°
(10μ§μλ‘ 15μ κ°μ)μ ~
Operator λ₯Ό μ μ©ν΄ 2μ§μ 11110000
(10μ§μλ‘ 240κ³Ό κ°μ)μ΄ λμλ€.
3. Bitwise AND Operator &
Bitwise AND Operator &
λ λ κ° μ¬μ΄μ μμΉν΄ μ°μ°λ κ°μ λ°ννλ€. λΉνΈμ κ° μλ¦Ώμκ° λͺ¨λ 1μ΄λ©΄ 1μ, κ·Έ μΈμλ
0μ λ°ννλ€.
let firstSixBits: UInt8 = 0b11111100
let lastSixBits: UInt8 = 0b00111111
let middleFourBits = firstSixBits & lastSixBits
printToBinary(number: middleFourBits) // 00111100
2μ§μ 11111100
κ³Ό 00111111
μ &
Operator λ₯Ό μ μ©ν΄ 2μ§μ 00111100
μ΄ λμλ€.
4. Bitwise OR Operator |
Bitwise OR Operator |
λ λ κ° μ¬μ΄μ μμΉν΄ μ°μ°λ κ°μ λ°ννλ€. λΉνΈμ κ° μλ¦Ώμκ° λͺ¨λ 0μ΄λ©΄ 0μ, κ·Έ μΈμλ
1μ λ°ννλ€.
let someBits: UInt8 = 0b10110010
let moreBits: UInt8 = 0b01011110
let combinedBits = someBits | moreBits
printToBinary(number: combinedBits) // 11111110
2μ§μ 10110010
κ³Ό 01011110
μ |
Operator λ₯Ό μ μ©ν΄ 2μ§μ 11111110
μ΄ λμλ€.
5. Bitwise XOR Operator ^
Bitwise XOR Operator(=Exclusive OR Operator) ^
λ λ κ° μ¬μ΄μ μμΉν΄ μ°μ°λ κ°μ λ°ννλ€. λΉνΈμ κ° μλ¦Ώμκ°
μλ‘ κ°μΌλ©΄ 0μ, λ€λ₯΄λ©΄ 1μ λ°ννλ€.
let firstBits: UInt8 = 0b00010100
let otherBits: UInt8 = 0b00000101
let outputBits = firstBits ^ otherBits
printToBinary(number: outputBits) // 00010001
2μ§μ 00010100
κ³Ό 00000101
μ ^
Operator λ₯Ό μ μ©ν΄ 2μ§μ 00010001
μ΄ λμλ€.
6. Bitwise Left and Right Shift Operators <<
>>
Bitwise Left Shift Operator <<
λ λͺ¨λ λΉνΈλ₯Ό μΌμͺ½μΌλ‘ μ΄λμν€λ©° μ μλ₯Ό 2λ°°λ‘ κ³±νλ ν¨κ³Όκ° μκ³ , Bitwise Right
Shift Operator >>
λ λͺ¨λ λΉνΈλ₯Ό μ€λ₯Έμͺ½μΌλ‘ μ΄λμν€λ©° μ μλ₯Ό λ°μΌλ‘ λλλ ν¨κ³Όκ° μλ€.
1 ) Shifting Behavior for Unsigned Integers
λΆνΈ μλ μ μμ Bit-Shifting νλμ λ€μκ³Ό κ°λ€.
- κΈ°μ‘΄μ λΉνΈλ₯Ό μμ²λ μ«μλ§νΌ μΌμͺ½ λλ μ€λ₯Έμͺ½μΌλ‘ μ΄λμν¨λ€.
- μ μμ μ μ₯ λ²μ(UInt8 μ μλ 8λΉνΈλ₯Ό κ°μ§λ©° 0 ~ 255 μ¬μ΄μ μ«μλ₯Ό μ μ₯)λ₯Ό λλ λΉνΈλ μ κ±°λλ€.
- λΉνΈ μ΄λμΌλ‘ λΉ κ³΅κ°μ
0
μ΄ μ½μ λλ€.
let shiftBits: UInt8 = 4
printToBinary(number: shiftBits) // 00000100
printToBinary(number: shiftBits << 1) // 00001000
printToBinary(number: shiftBits << 2) // 00010000
printToBinary(number: shiftBits << 5) // 10000000
printToBinary(number: shiftBits << 6) // 00000000
printToBinary(number: shiftBits >> 2) // 00000001
λ€μ μμ λ 16μ§μ Cascading Style Sheets μμκ°μ κ°κ° RGB λ‘ λΆλ¦¬νλ μ°μ°μ μννλ€.
let pink: UInt32 = 0xCC6699
let redComponent = (pink & 0xFF0000) >> 16 // redComponent is 0xCC, or 204
let greenComponent = (pink & 0x00FF00) >> 8 // greenComponent is 0x66, or 102
let blueComponent = pink & 0x0000FF // blueComponent is 0x99, or 153
16μ§μ Cascading Style Sheets μμκ°μ μ μ₯νκΈ° μν΄
UInt32
μμλ₯Ό μ¬μ©νκ³ μ μ₯λ μμμ λΆνμμ΄λ€.
- λΉ¨κ°μμ λΆλ¦¬νκΈ° μν΄ λΆνμμ λΉ¨κ°μμ μλ¦Ώκ°
0xFF0000
μ&
μ°μ°ν λ€μ μ€λ₯Έμͺ½μΌλ‘ 16λΉνΈλ₯Ό μ΄λμν¨λ€.- λ Ήμμ λΆλ¦¬νκΈ° μν΄ λΆνμμ λ Ήμμ μλ¦Ώκ°
0x00FF00
μ&
μ°μ°ν λ€μ μ€λ₯Έμͺ½μΌλ‘ 8λΉνΈλ₯Ό μ΄λμν¨λ€.- νλμμ λΆλ¦¬νκΈ° μν΄ νλμμ μλ¦Ώκ°
0x0000FF
μ&
μ°μ°νκ³ μλ¦Ώκ° μ΄λμ΄ νμ μμ΄ κ·Έλλ‘ μ’ λ£νλ€.
2 ) Shifting Behavior for Signed Integers
λΆνΈ μλ μ μμ Bit-Shifting νλμ μ΄μ§μΌλ‘ ννλλ λ°©λ² λλ¬Έμ λΆνΈ μλ μ μλ³΄λ€ λ 볡μ‘νλ€(λ€μ μμ λ λ¨μνλ₯Ό μν΄ 8λΉνΈμ λΆνΈ μλ μ μλ₯Ό μ¬μ©νμ§λ§ λμΌν μμΉμ΄ λͺ¨λ λΆνΈ μλ μ μμ μ μ©λλ€).
λΆνΈ μλ μ μλ 첫 λ²μ§Έ λΉνΈλ₯Ό λΆνΈλ‘ μ¬μ©νλ€. μ΄λ₯Ό Sign Bit
λ‘ 0μ μμλ₯Ό, 1μ μμλ₯Ό νννλ€. κ·Έλ¦¬κ³ λλ¨Έμ§
λΉνΈλ Value Bits
λ‘ μ€μ κ°μ μ μ₯νλ€. μμμΌ λλ λΆνΈ μλ μ μμ λμΌν λ°©μμ μ¬μ©νλ€.
λΆνΈ μλ μ μμ +4
νμ§λ§ μμμ κ²½μ° μ°λ¦¬κ° μ§κ΄μ μΌλ‘ μ¬μ©νλ λΆνΈ + μ λκ° μ«μ
μ ννλ₯Ό λμ§ μλλ€. +4
, -4
μ΄λ° μμ ννμ μ¬λμκ²
μ½κ³ μ΅μν κ²μ΄μ§ μ»΄ν¨ν° μΉνμ μ΄μ§ μκΈ° λλ¬Έμ΄λ€. μ»΄ν¨ν°λ Binary λ‘ λ°μ΄ν°λ₯Ό λ€λ£¨κΈ° λλ¬Έμ 2μ 보μλ₯Ό μ¬μ©ν΄ νννλ€.
λΆνΈ μλ μ μμ -4
2μ§μκ° κ°μ§ μ μλ 보μλ 2μ 보μμ 1μ 보μλ€.
- 2μ§μ μμ
+4
λ00000100
μ΄λ€.+4
μ 1μ 보μλ11111111 - 00000100
=111110110
μ΄λ€.+4
μ 2μ 보μλ 1μ 보μμ 1μ λν΄111110110 + 00000001
=11111100
μ΄ λλ€.
λΆνΈ μλ μ μμ -4
λ Sign Bit 1κ³Ό Value Bits 1111100
μΌλ‘ μ΄λ£¨μ΄μ§λ€. 10μ§μμμ μ΄ κ°μ 124λ₯Ό κ°λλ€.
λ°λΌμ, λΆνΈ μλ μ μμ μμ ννμ 2μ 보μλ₯Ό μ¬μ©ν΄ μμλ₯Ό νννλ Sign Bitμ 2μ 보μλ‘ ννλλ Value Bits
128 - 4
λ₯Ό νν λ°©μμΌλ‘ μ¬μ©νκ³ μμμ νμΈν μ μλ€. μ΄λ₯Ό Two's Complement Representation(2μ 보μ νν)
μ΄λΌ
λΆλ₯Έλ€.
2μ 보μ ννμ μ¬μ©νλ©΄ μ»΄ν¨ν° μ°μ°μ μ¬λ¬ μ₯μ μ κ°μ§ μ μλ€.
-1
+-4
μ κ°μ μ°μ°μ λ¨μν νμ€ μ΄μ§ λ§μ μΌλ‘ λ€λ£° μ μλ€.
2μ 보μλ‘ ννλ -4
μ -1
μ νμ€ μ΄μ§ λ§μ
μ°μ°μ ν ν μ μμ μ μ₯μ λ²μλ₯Ό λμ΄ μ΄λλ λͺ¨λ λΉνΈλ₯Ό μμ νλ©΄ μμ½κ² -5
μ
2μ 보μ ννμ μ»λλ€.
- Bitwise Shift Operators λ₯Ό Unsigned Integers μ μ μ¬νκ² λ€λ£° μ μλ€.
λΆνΈ μλ μ μμ Bitwise Left Shift Operator λ λΆνΈ μλ μ μμ λμΌνκ² νλνλ©° κ°μ 2λ°°λ‘ λλ¦°λ€.
λΆνΈ μλ μ μμ Bitwise Right Shift Operator λ λΆνΈ μλ μ μμ μ μ¬νλ, λΉνΈ μ΄λμΌλ‘ λΉ κ³΅κ°μ 0
μΌλ‘ μ±μ°λ κ²μ΄
μλ Sign Bit λ‘ λΉ μ리λ₯Ό μ±μ΄λ€. μ΄κ²μ Arithmetic Shift
λΌ νλ€.
3. Overflow Operators π©βπ»
1. Overflow Operators
Swift λ μ μ μμ λλ λ³μμ μ μ₯ν μ μλ κ°μ μ½μ νλ €κ³ νλ©΄, μ ν¨νμ§ μμ κ°μ μμ±μ νμ©νμ§ μμΌλ©° μλ¬λ₯Ό λ°μμν¨λ€. μ΄λ¬ν νλμ λ무 ν¬κ±°λ μμ κ°μ λ€λ£° λ μΆκ°μ μΈ Safety λ₯Ό μ 곡νλ€.
μλ₯Ό λ€μ΄ Int16
μ μλ 2^16 = 65,536 κ°μ κ°μ 0μ κΈ°μ€μΌλ‘ μ μ₯νλ―λ‘ -32,768 ~ 32,767 μ κ°μ μ μ₯ν μ μμΌλ―λ‘
μ΄ λ²μλ₯Ό μ΄κ³Όνλ μ«μλ₯Ό μ μ₯νλ €κ³ νλ©΄ μλ¬λ₯Ό λ°μμν¨λ€.
var potentialOverflow = Int16.max // 32,767
potentialOverflow += 1 // error, Swift runtime failure: arithmetic overflow
λ°λΌμ κ²½κ³κ° 쑰건μ μ½λ©ν λ μλ¬ μ²λ¦¬λ₯Ό μ κ³΅ν΄ μ μ°μ±μ λμΌ μ μλ€. νμ§λ§ μλ¬λ₯Ό λ°μμν€λ λμ &
λ₯Ό λΆμ¬ Overflow
Operators
λ₯Ό μ¬μ©ν μλ μλ€. Swift λ 3κ°μ§ Arithmetic Overflow Operators λ₯Ό μ 곡νλ€.
- Overflow addition
&+
- Overflow subtraction
&-
- Overflow multplication
&*
var potentialOverflow = Int16.max // 32,767
print(potentialOverflow &+ 1) // -32768
print(potentialOverflow &+ 2) // -32767
print(potentialOverflow &+ 3) // -32766
print(potentialOverflow &- 1) // 32766
print(potentialOverflow &* 2) // -2
2. Value Overflow
μ«μλ Positive, Negative μ λ°©ν₯μΌλ‘ μ€λ²νλ‘μ° λ μ μλ€.
μμμ μ μν printToBinary(number:)
ν¨μλ₯Ό λ€μκ³Ό κ°μ΄ κ³ μΉκ³ Overflow Operators μ λμμ μ΄ν΄λ³΄μ.
func printToBinary<T: BinaryInteger>(number: T) {
print("Binary: \(toBinary(number)), Decimal: \(number)")
func toBinary(_ number: T) -> String {
let absoluteNumber = abs(Int(number))
let binary = String(absoluteNumber, radix: 2)
if binary.count < 8 {
return String(repeating: "0", count: 8 - binary.count) + binary
} else {
return binary
}
}
}
λ€μμ λΆνΈ μλ μ μμ Positive λ°©ν₯μΌλ‘μ μ€λ²νλ‘μ° λ°μμ λν μμ λ€.
var unsignedOverflow = UInt8.max
printToBinary(number: unsignedOverflow)
// Binary: 11111111, Decimal: 255
unsignedOverflow = unsignedOverflow &+ 1
printToBinary(number: unsignedOverflow)
// Binary: 00000000, Decimal: 0
- λ³μ unsignedOverflow λ
UInt8
μ μ΅λκ°11111111
μ μ΄κΉκ°μΌλ‘ μ μ₯νλ€.- Overflow Addition Operator
&+
λ₯Ό μ¬μ©ν΄ κ°μ 1 μ¦κ°μν¨λ€.- μ μμ μ μ₯ λ²μλ₯Ό λλ λΉνΈλ μ κ±°λκ³
00000000
μ΄ λ¨κ² λλ€.
μ΄λ²μλ λΆνΈ μλ μ μμ Negative λ°©ν₯μΌλ‘μ μ€λ²νλ‘μ° λ°μμ λν μμ λ₯Ό μμ보μ.
var anotherUnsignedOverflow = UInt8.min
printToBinary(number: anotherUnsignedOverflow)
// Binary: 00000000, Decimal: 0
anotherUnsignedOverflow = anotherUnsignedOverflow &- 1
printToBinary(number: anotherUnsignedOverflow)
// Binary: 11111111, Decimal: 255
μ€λ²νλ‘μ°λ Signed Integers μμλ λ°μνλ€. λΆνΈ μλ μ μμ λͺ¨λ λ§μ , λΊμ μ λΉνΈ λ°©μμΌλ‘ μνλλ€.
var signedOverflow = Int8.min
printToBinary(number: signedOverflow)
// Binary: 10000000, Decimal: -128
signedOverflow = signedOverflow &- 1
printToBinary(number: signedOverflow)
// Binary: 01111111, Decimal: 127
- λ³μ signedOverflow λ
Int8
μ μ΅μκ°10000000
μ μ΄κΉκ°μΌλ‘ μ μ₯νλ€.- Overflow Subtraction Operator
&-
λ₯Ό μ¬μ©ν΄ κ°μ 1 κ°μμν¨λ€.- κ²°κ³Όκ°μ λΆνΈ λΉνΈκ° ν κΈλμ΄ μμκ° λμ΄
01111111
μ μ μ₯νλ€.
Signed Intergers, Unsigned Integers λ λμΌνκ² μ΅λκ°μ λμ΄μλ©΄ μ΅μκ°μΌλ‘, μ΅μκ°μ λμ΄μλ©΄ μ΅λκ°μΌλ‘ μνλλ€.
4. Precedence and Associativity π©βπ»
μ°μ°μ μ°μ μμ(precedence)λ λ€λ₯Έ μ°μ°μλ³΄λ€ λμ μ°μ μμλ₯Ό κ°λλ‘ ν΄ λ¨Όμ μ μ©λκ² νλ€. μ°μ°μ μ°κ΄μ±(associativity)μ λμΌν μ°μ μμλ₯Ό κ°λ μ°μ°μλ€μ΄ μΌμͺ½κ³Ό κ·Έλ£Ήν λ μ§, μ€λ₯Έμͺ½κ³Ό κ·Έλ£Ήν λ μ§λ₯Ό μ μνλ€.
Swift λ C μ²λΌ Multiplication Operator *
, Division Operator /
, Remainder Operator %
κ°μ
κ²λ€μ Addition Operator +
, Subtraction Operator -
κ°μ κ²λ€λ³΄λ€ λ λμ μ°μ μμλ₯Ό κ°λλ€. λμΌν μ°μ μμ
μ¬μ΄μμλ μΌμͺ½μΌλ‘ κ·Έλ£Ήν λλ€. μ¦, μνμ μ¬μΉμ°μ° μ°μ μμλ₯Ό κ·Έλλ‘ λ°λ₯Έλ€.
2 + 3 % 4 * 5
λ°λΌμ μ μ°μ°μ κ΄νΈλ₯Ό μ¬μ©ν΄ μ°μ μμλ₯Ό λͺ μμ μΌλ‘ νννλ©΄ λ€μκ³Ό κ°λ€.
2 + ((3 % 4) * 5)
(3 % 4)
λ 3 μ΄λ―λ‘ λ€μ μ°μ°μ 2 + (3 * 5)
κ° λκ³ , λ λ€μ (3 * 5)
λ 15 μ΄λ―λ‘ λ€μ μ°μ°μ 2 + 15
κ° λμ΄
μ°μ° κ²°κ³Όλ 17 μ΄ λλ€.
Swift μ
Operator Precedences
μOperator Associativity Rules
λ C λ Objective-C λ³΄λ€ λ κ°λ¨νκ³ μμΈ‘ κ°λ₯νλ€. μ΄κ²μ C-based μΈμ΄μ μμ ν μΌμΉνμ§ μμμ μλ―Ένλ―λ‘, κΈ°μ‘΄ μ½λλ₯Ό Swift λ‘ μ νν λ μ°μ°μ μνΈμμ©μ΄ μλνλλ‘ μλνλμ§ νμΈν΄μΌνλ€. Swift Standard Library κ° μ 곡νλ Operators λ Operator Declarations μμ νμΈν μ μλ€.
5. Operator Methods π©βπ»
1. Operator Methods
Classes μ Structures λ κΈ°μ‘΄ μ°μ°μλ₯Ό Overloading μμΌ μ체 ꡬνμ μ 곡ν μ μλ€.
Arithmetic Addition Operator λ λ νκ²μ μλνλ―λ‘ Binary Operator
μ΄λ©°, λ νκ² μ¬μ΄μ μμΉνλ―λ‘
Infix Operator
λ€. μλ μμ λ Custom Structure μμ Overloading μ ν΅ν΄ Arithmetic Addition
Operator +
κ° μ΄λ»κ² ꡬνλλμ§λ₯Ό 보μ¬μ€λ€.
struct Vector2D {
var x = 0.0, y = 0.0
}
extension Vector2D {
static func + (lhs: Vector2D, rhs: Vector2D) -> Vector2D {
Vector2D(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
}
}
Vector2D
μ Type Method λ‘ μ μλ μ°μ°μ +
λ μ΄λ¦μ΄ Arithmetic Addition Operator μ μΌμΉνκΈ° λλ¬Έμ
Overloading λλ€. Arithmetic Addition Operator κ° Binary Operator μ΄λ©°, Infix Operator μ΄λ―λ‘
μ΄ μ°μ°μ μμ λμΌν ννλ‘ μμ±λμλ€. λν λ§μ
μ°μ°μ 벑ν°μ νμ λμμ΄ μλλ―λ‘ Structures μ μ μ체μ ν¬ν¨μν€μ§ μκ³
Extensions λ₯Ό μ΄μ©ν΄ λΆλ¦¬μμΌ μ μνλ€.
let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
print("Combined Vector is (\(combinedVector.x), \(combinedVector.y)).")
// Combined Vector is (5.0, 5.0).
2. Prefix and Postfix Operators
μ μμ λ Binary Infix Operator
μ Custom Implementation μ 보μ¬μ£Όμλ€. Classes μ Structures λ
Standard Unary Operators
μ κ°μ κ²λ€λ ꡬνν μ μλ€.
Unary Operators
- Single Target μ λμμΌλ‘ μλνλ€.
- Operator κ° νκ² μμ μμΉνλ
Prefix Operators
, νκ² λ€μ μμΉνλPostfix Operators
2κ°μ§λ‘ λλλ€.Binary Operators
- Two Target μ λμμΌλ‘ μλνλ€.
- Operator κ° λ νκ² μ¬μ΄μ μμΉνλ€.
Unary Operators
λ func
keyword μμ prefix
λλ posfix
modifier λ₯Ό μμ±ν΄ μ μνλ€. λ€μ Operator λ
Unary Minus Operator λ‘ Prefix Operator λ‘ μ μλμλ€.
extension Vector2D {
static prefix func - (vector: Vector2D) -> Vector2D {
Vector2D(x: -vector.x, y: -vector.y)
}
}
let positive = Vector2D(x: 3.0, y: 4.0)
let negative = -positive
print("Negative Vector is (\(negative.x), \(negative.y)).")
// Negative Vector is (-3.0, -4.0).
let alsoPosotive = -negative
print("Also Positive Vector is (\(alsoPosotive.x), \(alsoPosotive.y)).")
// Also Positive Vector is (3.0, 4.0).
3. Compound Assignment Operators
Compound Assignment Operators
λ μ°μ°μμ Combine Assignment =
λ₯Ό κ²°ν©ν΄ λ§λ λ€. μλ₯Ό λ€μ΄ Addition
Assignment Operator +=
λ λ¨μΌ μ°μ°μΌλ‘ λ§μ
κ³Ό ν λΉμ κ²°ν©νλ€.
Compound Assignment Operators
μ left input parameter λ Operator Method λ‘λΆν° κ°μ΄ μ§μ μμ λλ―λ‘inout
μ΄ λμ΄μΌ νλ€.
λ€μμ Vector2D μ Addition Assignment Operator μ ꡬνμ΄λ€. μ¬κΈ°μ Arithmetic Addition Operator λ Operator Methodsμμ μ μλ κ²μ μ¬μ©νλ€.
extension Vector2D {
static func += (lhs: inout Vector2D, rhs: Vector2D) {
lhs = lhs + rhs
}
}
var original = Vector2D(x: 1.0, y: 2.0)
let vectorToAdd = Vector2D(x: 3.0, y: 4.0)
original += vectorToAdd
print("Original Vector is (\(original.x), \(original.y)) now.")
// Original Vector is (4.0, 6.0) now.
4. Equivalence Operators
κΈ°λ³Έμ μΌλ‘ Custom Classes μ Structures λ Equivalence Operators ==
μ !=
λ₯Ό ꡬνμ κ°μ§ μλλ€. λ°λΌμ
μ΄λ₯Ό ꡬνν λλ μΌλ°μ μΌλ‘ ==
μ°μ°μλ₯Ό ꡬννκ³ , !=
λ Swift Standard Library μ κΈ°λ³Έ ꡬνμ΄ ==
μ λΆμ μμ
μ΄μ©νλ€.
μ Vector2D μ Custom Equal to Operator ==
λ₯Ό ꡬννλ λ°©λ²μ λ κ°μ§κ° μλ€.
1 ) Infix Operator λ₯Ό μ§μ ꡬννκΈ°
extension Vector2D: Equatable {
static func == (lhs: Vector2D, rhs: Vector2D) -> Bool {
lhs.x == rhs.x && lhs.y == rhs.y
}
}
2 ) Protocol μ±νμΌλ‘ Swift κ° κ΅¬νμ μλμΌλ‘ ν©μ±νλλ‘ νκΈ°
extension Vector2D: Equatable {}
μ°λ¦¬λ Swift Protocols μ Adopting a Protocol Using a Synthesized Implementation μμ λ¨μν Protocol μ μ±ννλ κ² λ§μΌλ‘ Protocols κ° μ 곡νλ Default Implementations λ₯Ό Swift κ° μλμΌλ‘ ν©μ±ν΄ ꡬννλλ‘ ν μ μμμ νμΈνλ€.
let alpha = Vector2D(x: 2.0, y: 3.0)
let beta = Vector2D(x: 2.0, y: 3.0)
if alpha == beta {
print("These two vectors are equivalent.")
}
These two vectors are equivalent.
5. Impossible Operators to Overload
Classes μ Structures λ₯Ό ꡬνν λ λͺ¨λ Operators κ° Overloading κ°λ₯ν κ²μ μλλ€. Default Assignment
Operator =
λλ Ternary Conditional Operator a ? b : c
μ κ°μ΄ Overloading μ΄ νμ©λμ§ μλ
μ°μ°μκ° μ‘΄μ¬νλ€. Overloading μ΄ λΆκ°λ₯ν λͺ¨λ μ°μ°μ λͺ©λ‘μ λ€μ μΉμ
μ
Custom Operators λ‘ μ¬μ©ν μ μλ μ°μ°μ μμ νμΈν μ μλ€.
6. Custom Operators π©βπ»
1. Custom Operators
Swift κ° μ 곡νλ Standard Operators μΈμ Custom Operators λ₯Ό μ μΈνκ³ κ΅¬νν μ μλ€. Custom Operators
λ operator
keyword λ₯Ό μ¬μ©νλ©° prefix
, infix
, postfix
modifiers λ₯Ό κ°μ§λ©° Global Level
λ‘ μ μλλ€.
λ€μ μμ λ +++
λΌλ μλ‘μ΄ Prefix Operator λ₯Ό μ μνλ€.
prefix operator +++
μ΄ +++
μ°μ°μλ Swift μ μ‘΄μ¬νλ Operators κ° μλλ―λ‘ Protocols λ₯Ό μ±ννλλ‘ ν΄ κ΅¬νμ ν©μ±νλλ‘ ν μ μλ€. μ΄
μ Operators λ₯Ό μ¬μ©ν΄ μ μνλ €λ μμ
μ μ¬μ©μκ° μ§μ ꡬνν΄μΌνλ©°, κ·Έ ꡬνμ μ¬μ©μκ° μ μν νΉμ context λ΄μ μλ―Έκ°
λΆμ¬λλ€.
prefix operator +++
extension Vector2D {
static prefix func +++ (vector: inout Vector2D) -> Vector2D {
vector += vector
return vector
}
}
μ΄μ Vector2D λ κΈ°μ‘΄μ¬ μ‘΄μ¬νμ§ μλ μ¬μ©μ μ μ μ°μ°μ +++
λ₯Ό μ¬μ©ν΄ κ°μ 2λ°°λ‘ λ§λλ μ°μ°μ μνν μ μλ€.
var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
let afterDoubling = +++toBeDoubled
print("After Doubling Vector is (\(afterDoubling.x), \(afterDoubling.y)).")
// After Doubling Vector is (2.0, 8.0).
1 ) Custom Operators λ‘ μ¬μ©ν μ μλ μ°μ°μ
- ASCII λ¬Έμ
/
,=
,-
,+
,!
,*
,%
,<
,>
,&
,|
,^
,?
- λ€μ λ¬Έλ²κ³Ό μΌμΉνλ μ°μ°μ
Grammar of operators
operator β operator-head operator-characters?
operator β dot-operator-head dot-operator-characters
operator-head β / | = | - | + | ! | * | % | < | > | & | | | ^ | ~ | ?
operator-head β U+00A1βU+00A7
operator-head β U+00A9 or U+00AB
operator-head β U+00AC or U+00AE
operator-head β U+00B0βU+00B1
operator-head β U+00B6, U+00BB, U+00BF, U+00D7, or U+00F7
operator-head β U+2016βU+2017
operator-head β U+2020βU+2027
operator-head β U+2030βU+203E
operator-head β U+2041βU+2053
operator-head β U+2055βU+205E
operator-head β U+2190βU+23FF
operator-head β U+2500βU+2775
operator-head β U+2794βU+2BFF
operator-head β U+2E00βU+2E7F
operator-head β U+3001βU+3003
operator-head β U+3008βU+3020
operator-head β U+3030
operator-character β operator-head
operator-character β U+0300βU+036F
operator-character β U+1DC0βU+1DFF
operator-character β U+20D0βU+20FF
operator-character β U+FE00βU+FE0F
operator-character β U+FE20βU+FE2F
operator-character β U+E0100βU+E01EF
operator-characters β operator-character operator-characters?
dot-operator-head β .
dot-operator-character β . | operator-character
dot-operator-characters β dot-operator-character dot-operator-characters?
infix-operator β operator
prefix-operator β operator
postfix-operator β operator
2 ) Custom Operators λ‘ μ¬μ©ν μ μλ μ°μ°μ
λ€μ μ°μ°μλ€μ μμ½λμ΄μμΌλ©°, Overloading νκ±°λ Custom Operators λ‘ μ¬μ©ν μ μλ€.
- Tokens λ‘ μ¬μ©ν μ μλ μ°μ°μ:
=
,->
,//
,/*
,*/
,.
- Prefix Operators λ‘ μ¬μ©ν μ μλ μ°μ°μ:
<
,&
,?
- Infix Operators λ‘ μ¬μ©ν μ μλ μ°μ°μ:
?
- Postfix Operators λ‘ μ¬μ©ν μ μλ μ°μ°μ:
>
,!
,?
2. Precedence for Custom Infix Operators
λͺ¨λ Custom Infix Operators
λ κΈ°λ³Έ Infix Operators μ λ§μ°¬κ°μ§λ‘ νΉμ μ°μ μμ κ·Έλ£Ήμ μνκ² λλ€. μ μΈν λ
μ°μ μμ κ·Έλ£Ήμ λͺ
μν μ μμΌλ©°, λͺ
μλμ§ μμ μ°μ°μλ Default Precedence Group μ μνκ² λλλ° μ΄κ²μ Ternary
Conditional Operator μ λ°λ‘ μμ μμΉνκ²λλ€.
λ€μ μμ λ New Custom Infix Operator +-
λ₯Ό μ μΈ λ° μ μνλ€. μ΄ μ°μ°μλ μ°μ μ°μ°μ νλ―λ‘ Addition
Precednece κ·Έλ£Ήμ μνλλ‘ μ μΈλμλ€.
infix operator +-: AdditionPrecedence
extension Vector2D {
static func +- (lhs: Vector2D, rhs: Vector2D) -> Vector2D {
Vector2D(x: lhs.x + rhs.x, y: lhs.y - rhs.y)
}
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
print("Plus Minus Vector is (\(plusMinusVector.x), \(plusMinusVector.y)).")
// Plus Minus Vector is (4.0, -2.0).
Prefix Operators
λλPostfix Operators
λ₯Ό μ μν λλ μ°μ μμλ₯Ό μ§μ νμ§ μλλ€. λ§μ½ νΌμ°μ°μ(operand)μ λμ λͺ¨λ μ μ©ν κ²½μ°Postfix Operators
κ° λ λμ μ°μ μμλ₯Ό κ°μ Έ λ¨Όμ μ μ©λλ€.
7. Result Builders π©βπ»
1. The Problem That Result Builders Solve
κ²°κ³Ό λΉλ (result builder) λ 리μ€νΈ (list) λ νΈλ¦¬ (tree) μ κ°μ μ€μ²©λ λ°μ΄ν°λ₯Ό μμ°μ€λ½κ³ μ μΈμ μΈ λ°©μμΌλ‘ μμ±νκΈ° μν ꡬ문μ μΆκ°νλ νμ μ λλ€. κ²°κ³Ό λΉλλ₯Ό μ¬μ©νλ μ½λλ 쑰건μ μ΄κ±°λ λ°λ³΅λλ λ°μ΄ν°μ μ‘°κ°μ μ²λ¦¬νκΈ° μν΄ if μ for μ κ°μ Swift ꡬ문μ ν¬ν¨ν μ μμ΅λλ€. μλ μ½λλ λ³κ³Ό ν μ€νΈλ₯Ό μ¬μ©νμ¬ νμ€λ‘ 그리기 μν΄ λͺκ°μ§ νμ μ μ μν©λλ€.
Result Builder
λ νλμ Type μΌλ‘, List λ Tree μ κ°μ Nested Data
λ₯Ό μμ°μ€λ½κ³ μ μΈμ μΌλ‘ μμ±νκΈ° μν Syntax λ₯Ό μ μνλ€.
λ€μ μμ λ ν μ€μ λ³κ³Ό λ¬Έμλ₯Ό 그리기 μν΄ λͺ κ°μ§ Types λ₯Ό μ μνλ€.
protocol Drawable {
func draw() -> String
}
struct Line: Drawable {
var elements: [Drawable]
func draw() -> String {
elements.map { $0.draw() }.joined(separator: "")
}
}
struct Text: Drawable {
var content: String
init(_ content: String) {
self.content = content
}
func draw() -> String {
content
}
}
struct Space: Drawable {
func draw() -> String {
" "
}
}
struct Stars: Drawable {
var length: Int
func draw() -> String {
String(repeating: "*", count: length)
}
}
struct AllCaps: Drawable {
var content: Drawable
func draw() -> String {
content.draw().uppercased()
}
}
Drawable
protocol μdraw()
λ©μλλ₯Ό ꡬννλλ‘ κ°μ ν¨μΌλ‘μ¨ μ μ΄λ λͺ¨μκ³Ό κ°μ 그릴 μ μλ νλͺ©μ λν μꡬμ¬νμ μ μνλ€.Line
structure λ λ€λ₯Έ Drawable μ μμ μ property μ λ°°μ΄λ‘ μ μ₯ν¨μΌλ‘μ¨ λλΆλΆμ 그리λ κ²μ λν΄ μ΅μμ 컨ν μ΄λμ μν μ νλ€. Line structure λ μ€μ 그리기 μν΄draw()
λ₯Ό νΈμΆνκ³ μ΄ λ©μλλ 컨ν μ΄λ λ΄ λ€λ₯Έ Drawable μ΄ μμ μdraw()
λ₯Ό νΈμΆν΄ κ·Έλ¦Όμ 그리λλ‘ ν λ€joined(separator:)
λ©μλλ₯Ό μ΄μ©ν΄ λ¬Έμμ΄ κ²°κ³Όλ₯Ό λ¨μΌ String μΌλ‘ λ§λ λ€.Text
structure λ λ¬Έμμ΄μ νλμ κ·Έλ¦¬κΈ°λ‘ wrapping μν€κ³ ,Space
structure λ νλμ 곡백μ κ·Έλ¦¬κ³ ,Stars
structure λ μ£Όμ΄μ§ κ°μ λ§νΌ λ³μ κ·Έλ¦°λ€.AllCaps
structure λ λ€λ₯Έ Drawable μ λλ¬Έμλ‘ λ³κ²½νλ μν μ νλ€.
μ΄ Structures λ₯Ό μ¬μ©ν΄ λ€μκ³Ό κ°μ΄ One Line String μ 그릴 μ μλ€.
let name: String? = "Hogwarts"
let manualDrawing = Line(elements: [
Stars(length: 3),
Text("Hello"),
Space(),
AllCaps(content: Text("\(name ?? "World")!")),
Stars(length: 2)
])
print(manualDrawing.draw()) // ***Hello HOGWARTS!**
μ½λλ μ μλνμ§λ§ AllCaps μμ λ λ€λ₯Έ κ΄νΈλ₯Ό ν¬ν¨νλ μΈμ€ν΄μ€ μμ± κ΅¬λ¬Έμ΄ λ€μ΄κ°λ κ²μ μ½λλ₯Ό μ½κΈ° μ΄λ ΅κ² λ§λ λ€.
2. Define Result Builders
Result Builder
λ μ½λλ₯Ό μ’ λ Swift μ€λ½κ³ μ½κΈ° μ½κ² λ§λ€μ΄μ€λ€. Result Builder λ νμ
μ μΈμ @resultBuilder
Attribute λ₯Ό μμ±ν΄ μ μνλ€. λ€μ μμ λ Declarative Syntax λ₯Ό μ¬μ©ν΄ drawing
μμ
μ λ¬μ¬νλ DrawingBuilder
λ₯Ό μ μνλ€.
@resultBuilder
struct DrawingBuilder {
static func buildBlock(_ components: Drawable...) -> Drawable {
Line(elements: components)
}
static func buildEither(first: Drawable) -> Drawable {
first
}
static func buildEither(second: Drawable) -> Drawable {
second
}
}
DrawingBuilder
structure λ Result Builder Syntax μ μΌλΆλ₯Ό ꡬννλ 3κ°μ λ©μλλ₯Ό μ μνλ€.
buildBlock(_:)
λ©μλλ μ½λ λΈλμLine
μ 그리기 μν μ§μμ μΆκ°νλ€.buildEither(first:)
λ©μλμbuildEither(second:)
λ©μλλif-else
μ λν μ§μμ μΆκ°νλ€.
3. Result Builders in Action
μμμ μ μν DrawingBuilder
λ₯Ό μ¬μ©νκΈ° μν΄ ν¨μμ Parameter μ @DrawingBuilder
attribute λ₯Ό μ μ©ν μ
μμΌλ©°, μ΄λ ν¨μμ μ λ¬λ Closure λ₯Ό Result Builder κ° ν΄λΉ Closure μμ μμ±νλ κ°μΌλ‘ λ³ννλ€.
func draw(@DrawingBuilder content: () -> Drawable) -> Drawable {
content()
}
func caps(@DrawingBuilder content: () -> Drawable) -> Drawable {
AllCaps(content: content())
}
func makeGreeting(for name: String? = nil) -> Drawable {
let greeting = draw(content: {
Stars(length: 3)
Text("Hello")
Space()
caps(content: {
Text("\(name ?? "World")!")
})
Stars(length: 2)
})
return greeting
}
draw(_:)
μcaps(_:)
ν¨μλ λ λ€@DrawingBuilder
attribute κ° μ μ©λ Single Closure λ₯Ό arguemnt λ‘ λ°λλ€. μ΄κ²μ μΌλ° ν¨μμμ Parameter Type μ΄ Closure μΌ λμ μ¬μ©λ²κ³Ό λμΌνλ€. μ°λ¦¬λ μ΄κ²μ μ΄λ―Έ Autoclosure Type Parameters μμ Autoclosure λ₯Ό μ¬μ©νμ§ μμ μΌλ° ν¨μμ Parameter κ° Closure μΌ λ μ¬μ©ν΄λ³Έ μ μ΄ μλ€.
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func serve(customer customerProvider: () -> String) {
print("Now serving \(customerProvider())!")
}
// serve(customer: { customersInLine.remove(at: 0) }) // Now serving Chris!
// with trailing closure
serve {
customersInLine.remove(at: 0)
}
Now serving Chris!
makeGreeting(for:)
ν¨μλ name μ parameter λ‘ λ°μ κ°μΈν μΈμ¬λ§μ 그리λ λ° μ¬μ©νλ€. μμμ Result Builders λ List λ Tree μ κ°μ Nested Data λ₯Ό μμ°μ€λ½κ³ μ μΈμ μΌλ‘ μμ±νκΈ° μν Syntax λ₯Ό μ μνλ Type μ΄λΌκ³ νλ€. μ¦, μ΄κ²μ Swift κ° μΈμ΄ λ 벨μμ μ§μνλ Monad λΌ λ³Ό μ μλ€. μ΄κ²μ pipe μ reduce μ νΉμ±λ€μ μ‘°κΈμ© μμ΄ λμ κ²μ²λΌ 보μ΄κΈ°λ νλ€. νκ°μ§ νμ€ν κ²μ Result Builders λ κ²°κ΅ Monad λ‘ λ°μ΄ν°λ₯Ό μ½κ² λ€λ£¨κΈ° μνContainer
μν μ νλ€λ κ²μ΄λ€.
μ΄μ makeGreeting(for:)
ν¨μλ₯Ό Trailing Closures λ₯Ό μ¬μ©ν΄ μ’ λ κ°λ΅νκ² ννν΄λ³΄μ.
func draw(@DrawingBuilder content: () -> Drawable) -> Drawable {
content()
}
func caps(@DrawingBuilder content: () -> Drawable) -> Drawable {
AllCaps(content: content())
}
func makeGreeting(for name: String? = nil) -> Drawable {
draw {
Stars(length: 3)
Text("Hello")
Space()
caps {
Text("\(name ?? "World")!")
}
Stars(length: 2)
}
}
κΈ°μ‘΄μ
let manualDrawing = Line(elements: [
Stars(length: 3),
Text("Hello"),
Space(),
AllCaps(content: Text("\(name ?? "World")!")),
Stars(length: 2)
])
μ λΉκ΅ν΄λ³΄λ©΄ ν¨μ¬ μ μΈμ μΈ λ¬Έλ²μ΄ λμλ€. μ μλνλμ§ νμΈν΄λ³΄μ.
let genericGreeting = makeGreeting()
print(genericGreeting.draw()) // ***Hello WORLD!**
ν¨μλ₯Ό μ¬μ©ν΄ μ μΈμ μΌλ‘ λ³κ²½νκΈ° λλ¬Έμ κ°λ μ±μ΄ μ’μμ‘μ λΏ μλλΌ μ¬μ¬μ©μ±λ μ’μμ‘λ€.
let personGreeting = makeGreeting(for: "Hogwarts")
print(personGreeting.draw()) // ***Hello Hogwarts!**
@DrawingBuilder
λ₯Ό attribute λ‘ μ¬μ©νλ€λ κ²μ DrawingBuilder κ° μ μν Syntax λ₯Ό μ¬μ©νλ€λ κ²μ΄λ―λ‘
Closure μ μ€νμν€κΈΈ μνλ μ½λλ₯Ό λͺ¨μ νλμ μ½λ λΈλμΌλ‘ Wrapping μν€κ³ , μ΄κ²μ do
λͺ
λ ΉμΌλ‘ evalution νλ
κ²κ³Ό κ°λ€κ³ λ³Ό μ μλ€. λ°λΌμ draw(content:)
ν¨μμ Trailing Closures λ₯Ό μ¬μ©ν΄ μ¬λ¬ μ½λλ₯Ό νλμ λΈλμΌλ‘ λ¬Άμ
κ² μ²λΌ caps(content:)
ν¨μ μμ λμΌνκ² μ¬λ¬ μ½λλ₯Ό νλμ λΈλμΌλ‘ λ¬Άμ μ μλ€.
let name: String? = "Hogwarts"
let capsDrawing = caps {
let partialDrawing: Drawable
if let name = name {
partialDrawing = DrawingBuilder.buildEither(first: Text("\(name)!"))
} else {
partialDrawing = DrawingBuilder.buildEither(second: Text("World!"))
}
return partialDrawing
}
print(capsDrawing) // AllCaps(content: __lldb_expr_156.Text(content: "Hogwarts!"))
print(capsDrawing.draw()) // HOGWARTS!
μ¬κΈ°μ caps(content:)
κ° μ€ννκ³ μ νλ μ½λ λΈλμ 보μ. if-else
ꡬ문μ buildEither(first:)
μ
buildEither(second:)
λ©μλμ λν νΈμΆλ‘ λ³ννλ€. μ¦, Monad μ μΌμ’
μ΄λ―λ‘ λͺ¨λ λ°μ΄ν°λ₯Ό Drawable
λ‘ λ€λ£¨κ²
νλ κ²μ΄λ€. νμ¬ μ½λμμ buildEither(first:)
μ buildEither(second:)
κ° νλ μΌμ΄ λμΌνκΈ° λλ¬Έμ μμμ
Ternary Operator λ₯Ό μ¬μ©ν΄ μ²λ¦¬νμ§λ§ μλ‘ λ€λ₯Έ λ‘μ§μ μΆκ°ν΄ κ³ μ μ λμμ νλλ‘ μ μΈν μ μμμ μλ―Ένλ€.
μ΄λ²μλ DrawingBuilder μ buildArray(_:)
λ©μλλ₯Ό μΆκ°ν΄λ³΄μ.
extension DrawingBuilder {
static func buildArray(_ components: [Drawable]) -> Drawable {
Line(elements: components)
}
}
μ΄ λ©μλλ Drawable
λ°μ΄ν°λ₯Ό Collection μΌλ‘ λ§λ€μ΄ for-loop
λ₯Ό μ¬μ© κ°λ₯νκ² λ§λ€μ΄μ€λ€.
let manyStars = draw {
Text("Stars:")
for length in 1...3 {
Space()
Stars(length: length)
}
}
print(manyStars.draw()) // Stars: * ** ***
νμ¬ Result Builders
λ₯Ό ν΅ν΄ μ μν μ μλ λ©μλλ buildBlock(_:)
κ³Ό buildEither(first:)
,
buildEither(second:)
λ₯Ό ν¬ν¨ν΄ 10κ°κ° μ‘΄μ¬νλ€.
@resultBuilder
struct ArrayBuilder {
typealias Component = [Int]
typealias Expression = Int
static func buildExpression(_ element: Expression) -> Component {
return [element]
}
static func buildOptional(_ component: Component?) -> Component {
guard let component = component else { return [] }
return component
}
static func buildEither(first component: Component) -> Component {
return component
}
static func buildEither(second component: Component) -> Component {
return component
}
static func buildArray(_ components: [Component]) -> Component {
return Array(components.joined())
}
static func buildBlock(_ components: Component...) -> Component {
return Array(components.joined())
}
// ...
}
Result Builders λ¬Έλ²μ μ 체 λ νΌλ°μ€λ Swift Docs Language Reference - Attributes/Result Builder λ₯Ό μ°Έκ³ νλ€.
Reference
- βAdvanced Operators.β The Swift Programming Language Swift 5.9. accessed Oct. 14, 2023, Swift Docs Chapter 27 - Advanced Operators.
- βOperator Declarations.β Apple Developer Documentation. accessed Oct. 17, 2023, Apple Developer Documentation - Swift/Swift Standard Library/Operator Declarations.
- βLexical Structure.β The Swift Programming Language Swift 5.9. accessed Oct. 23, 2023, Swift Lexical Structure.
- βAttributes.β The Swift Programming Language Swift 5.9. accessed Oct. 24, 2023, Swift Docs Language Reference - Attributes/Result Builder.