[Swift๐Ÿฆฉ] #28 ๊ณ ๊ธ‰ ์—ฐ์‚ฐ์ž

๋˜์ƒยท2022๋…„ 4์›” 29์ผ
0

iOS

๋ชฉ๋ก ๋ณด๊ธฐ
44/47
post-thumbnail
  • ๊ธฐ๋ณธ ์—ฐ์‚ฐ์ž ์™ธ์—๋„ ๋น„ํŠธ ์—ฐ์‚ฐ์ž ๊ฐ™์€ ๊ณ ๊ธ‰ ์—ฐ์‚ฐ์ž๊ฐ€ ์ œ๊ณต๋œ๋‹ค.
  • Swift ์˜ ์—ฐ์‚ฐ์ž๋Š” ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ์—†๋‹ค!!! ๊ทธ๋ž˜์„œ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋˜๋Š” ์—ฐ์‚ฐ์ž๋Š” ๋”ฐ๋กœ ์žˆ์Œ.
  • ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ค‘์œ„, ์ ‘๋‘์‚ฌ, ์ ‘๋ฏธ์‚ฌ, ํ• ๋‹น ์—ฐ์‚ฐ์ž๋ฅผ ์ž์œ ๋กญ๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•ด๋‹น ์—ฐ์‚ฐ์ž ์ง€์›์„ ์œ„ํ•ด extension ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ!!
  • ์—ฌ๊ธฐ ์— ๋” ๋งŽ์€ ์—ฐ์‚ฐ์ž์— ๋Œ€ํ•œ ์„ค๋ช…์ด ์žˆ๋‹ค.

1. ๋น„ํŠธ ์—ฐ์‚ฐ์ž

  • ๋ฐ์ดํ„ฐ ๋น„ํŠธ๋ฅผ ์กฐ์ž‘.
  • low-level ํ”„๋กœ๊ทธ๋ž˜๋ฐ
  • ๋ฐ์ดํ„ฐ ์ธ์ฝ”๋”ฉ, ๋””์ฝ”๋”ฉ ๋“ฑ์„ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

Bitwise NOT Operator ~

  • ๋ชจ๋“  ๋น„ํŠธ๋ฅผ ๋ฐ˜์ „ํ•œ๋‹ค.

let initialBits: UInt8 = 0b00001111
let invertedBits = ~initialBits  // equals 11110000 240

Bitwise AND Operator &

  • ๋‘ ์ˆซ์ž์˜ ๋น„ํŠธ๋ฅผ ๊ฒฐํ•ฉํ•œ๋‹ค.
  • ๋‘˜ ๋‹ค 1์ด๋ฉด 1, ์•„๋‹ˆ๋ฉด 0

let firstSixBits: UInt8 = 0b11111100
let lastSixBits: UInt8  = 0b00111111
let middleFourBits = firstSixBits & lastSixBits  // equals 00111100

Bitwise OR Operator |

let someBits: UInt8 = 0b10110010
let moreBits: UInt8 = 0b01011110
let combinedbits = someBits | moreBits  // equals 11111110

Bitwise XOR Opertor ^

  • ๋น„ํŠธ๊ฐ€ ๊ฐ™์œผ๋ฉด 0, ๋‹ค๋ฅด๋ฉด 1 ๋ฐ˜ํ™˜

let firstBits: UInt8 = 0b00010100
let otherBits: UInt8 = 0b00000101
let outputBits = firstBits ^ otherBits  // equals 00010001

Bitwise Shift Operators << >>

  • << : ์™ผ์ชฝ์œผ๋กœ ๋’ค์˜ ์ˆซ์ž ๋น„ํŠธ๋งŒํผ ์ด๋™. ( * 2 ^ (์ˆซ์ž๊ฐœ์ˆ˜) ) ์™€ ๊ฐ™์Œ
  • >> : ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๋’ค์˜ ์ˆซ์ž ๋น„ํŠธ๋งŒํผ ์ด๋™. ( / 2 ^ (์ˆซ์ž๊ฐœ์ˆ˜) ) ์™€ ๊ฐ™์Œ

๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜์—์„œ Shift - ๋…ผ๋ฆฌ์  ์ด๋™

  1. ๊ธฐ์กด ๋น„ํŠธ๋Š” ์š”์ฒญ๋œ ์ˆซ์ž๋งŒํผ ์˜ค๋ฅธ์ชฝ/์™ผ์ชฝ์œผ๋กœ ์ด๋™.
  2. ์ •์ˆ˜ ์ €์žฅ๋ฒ”์œ„๋ฅผ ๋„˜์€ ๋น„ํŠธ๋Š” ์‚ญ์ œ๋จ.
  3. ์›๋ž˜ ๋น„ํŠธ๊ฐ€ ์™ผ์ชฝ/์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™ํ•œ ํ›„ ๋นˆ ์ž๋ฆฌ์—๋Š” 0์ด ๋“ค์–ด๊ฐ.

let shiftBits: UInt8 = 4   // 00000100 in binary
shiftBits << 1             // 00001000
shiftBits << 2             // 00010000
shiftBits << 5             // 10000000
shiftBits << 6             // 00000000
shiftBits >> 2             // 00000001

์ƒ‰์ƒ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ธ์ฝ”๋”ฉ, ๋””์ฝ”๋”ฉ ํ•˜๋Š” ์˜ˆ์ œ.

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

๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜์—์„œ Shift

  • ๋งจ ์•ž ๋น„ํŠธ๊ฐ€ ๋ถ€ํ˜ธ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋น„ํŠธ๋ผ์„œ ๋ณต์žกํ•˜๋‹ค.
  • ๋งจ ์•ž ๋น„ํŠธ๋Š” ๋ถ€ํ˜ธ, ๊ทธ ๋’ค์˜ 7์ž๋ฆฌ๊ฐ€ ์‹ค์ œ ์ˆซ์ž๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.
  • ์Œ์ˆ˜๋Š” 2์˜ ๋ณด์ˆ˜๋กœ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    • 1์˜ ๋ณด์ˆ˜ -> ์ „๋ถ€ ๋ฐ˜์ „ํ•œ ํ›„
    • 2์˜ ๋ณด์ˆ˜ -> 1 ๋”ํ•จ.
  • ex) 4 = 00000100 -> 1์˜ ๋ณด์ˆ˜ 11111011 -> +1 11111100 -> -4

์žฅ์ 
1. ๋ถ€ํ˜ธ๋น„ํŠธ๋Š” ๊ทธ๋ƒฅ ๋‘๊ณ  ๋‚˜๋จธ์ง€ ์ž๋ฆฌ๋กœ ์ด์ง„ ๋ง์…ˆ์„ ํ•˜๊ณ , int ํฌ๊ธฐ๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๊ฒƒ ์ž๋ฅด๋ฉด ๋จ.
2. ๋น„ํŠธ๋ฅผ ์™ผ์ชฝ ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ, ์™ผ์ชฝ์— ๋น„์–ด์žˆ๋Š” ๋ชจ๋“  ๋น„ํŠธ์— 0์ด ์•„๋‹ˆ๋ผ ํ•ด๋‹น ๋ถ€ํ˜ธ ๋น„ํŠธ๋ฅผ ์ฑ„์šฐ๊ฒŒ ๋œ๋‹ค. -> ๋ถ€ํ˜ธ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ์—ฐ์‚ฐ.


2. ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ์—ฐ์‚ฐ์ž

  • Swift ์—์„œ๋Š” ํ—ˆ์šฉ ๋ฒ”์œ„๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ์—๋Ÿฌ๋ฅผ ๋‚ด์„œ ์•ˆ์ •์„ฑ์„ ์ œ๊ณต.
  • ํ•˜์ง€๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋น„ํŠธ๋ฅผ ์ž˜๋ผ์„œ ์“ฐ๋ ค๊ณ  ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋ฅผ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
  • &+ &- &* ๋ฅผ ์ด์šฉํ•˜์ž.

๊ฐ’ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ

  • ๋ถ€ํ˜ธ ์—†๋Š” ์ •์ˆ˜์—์„œ๋Š” -1 ๊ณผ ์–‘์ˆ˜ ๋งˆ์ง€๋ง‰ ๊ฐ’์—์„œ,

var unsignedOverflow = UInt8.min
// unsignedOverflow equals 0, which is the minimum value a UInt8 can hold
unsignedOverflow = unsignedOverflow &- 1
// unsignedOverflow is now equal to 255
  • ๋ถ€ํ˜ธ ์žˆ๋Š” ์ •์ˆ˜์—์„œ๋Š” ์Œ์ˆ˜ ๋งˆ์ง€๋ง‰ ๊ฐ’, ์–‘์ˆ˜ ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ์˜ค๊ฐˆ ๋•Œ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

var signedOverflow = Int8.min
// signedOverflow equals -128, which is the minimum value an Int8 can hold
signedOverflow = signedOverflow &- 1
// signedOverflow is now equal to 127

3. ์šฐ์„ ์ˆœ์œ„์™€ ์—ฐ๊ด€์„ฑ

  • ์—ฐ์‚ฐ์ž ์šฐ์„ ์ˆœ์œ„.
  • ์™ผ์ชฝ์— ์žˆ๋Š” ํ‘œํ˜„ ๊ด€๋ จ์ธ์ง€ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ํ‘œํ˜„ ๊ด€๋ จ์ธ์ง€๋ฅผ ๋”ฐ์ ธ์„œ ์™ผ์ชฝ์—์„œ ๊ทธ๋ฃนํ™”ํ•˜๊ฑฐ๋‚˜ ์˜ค๋ฅธ์ชฝ์—์„œ ๊ทธ๋ฃนํ™”ํ•œ๋‹ค.
2 + 3 % 4 * 5 // this equals 17
2 + ((3 % 4) * 5)

NOTE : C์–ธ์–ด ์šฐ์„ ์ˆœ์œ„์™€ ์™„๋ฒฝํ•˜๊ฒŒ ์ผ์น˜ํ•˜์ง„ ์•Š์„ ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ ํฌํŒ… ์‹œ ์ฃผ์˜ํ•˜์ž.


4. ์—ฐ์‚ฐ์ž ๋ฉ”์„œ๋“œ

  • ๊ธฐ์กด ์—ฐ์‚ฐ์ž์˜ ์ž์ฒด ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์—ฐ์‚ฐ์ž ์˜ค๋ฒ„๋กœ๋”ฉ
// ๋ฒกํ„ฐ์˜ ๋ง์…ˆ ์—ฐ์‚ฐ์ž ์˜ค๋ฒ„๋กœ๋”ฉ
struct Vector2D {
    var x = 0.0, y = 0.0
}

extension Vector2D {
    static func + (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y + right.y)
    }
}

let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
// combinedVector is a Vector2D instance with values of (5.0, 5.0)

Prefix and Postfix Operators

  • ์—ฐ์‚ฐ์ž๊ฐ€ ์•ž์— ์˜ค๋ฉด ์ ‘๋‘์‚ฌ ์—ฐ์‚ฐ์ž -3 +3
  • ๋’ค์— ์˜ค๋ฉด ์ ‘๋ฏธ์‚ฌ ์—ฐ์‚ฐ์ž b!
extension Vector2D {
    static prefix func - (vector: Vector2D) -> Vector2D {
        return Vector2D(x: -vector.x, y: -vector.y)
    }
}

let positive = Vector2D(x: 3.0, y: 4.0)
let negative = -positive
// negative is a Vector2D instance with values of (-3.0, -4.0)
let alsoPositive = -negative
// alsoPositive is a Vector2D instance with values of (3.0, 4.0)

๋ณตํ•ฉ ํ• ๋‹น ์—ฐ์‚ฐ์ž

  • ์—ฐ์‚ฐ ํ•˜๊ณ  ํ• ๋‹น๊นŒ์ง€ ํ•˜๋Š” ๊ฒƒ!
  • ํ• ๋‹นํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์™ผ์ชฝ ์—ฐ์‚ฐ์ž๋Š” inout ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์„ค์ •ํ•œ๋‹ค.
extension Vector2D {
    static func += (left: inout Vector2D, right: Vector2D) {
        left = left + right
    }
}

var original = Vector2D(x: 1.0, y: 2.0)
let vectorToAdd = Vector2D(x: 3.0, y: 4.0)
original += vectorToAdd
// original now has values of (4.0, 6.0)

NOTE : = ๊ณผ ์‚ผํ•ญ์—ฐ์‚ฐ์ž๋Š” ์˜ค๋ฒ„๋กœ๋”ฉ ๋ถˆ๊ฐ€๋Šฅ.


๋“ฑ๊ฐ€ ์—ฐ์‚ฐ์ž

  • ์‚ฌ์šฉ์ž ์ •์˜ ํด๋ž˜์Šค์—์„œ == != ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Equatable ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๊ฒŒ ํ•ด์•ผํ•œ๋‹ค.
extension Vector2D: Equatable {
    static func == (left: Vector2D, right: Vector2D) -> Bool {
        return (left.x == right.x) && (left.y == right.y)
    }
}

let twoThree = Vector2D(x: 2.0, y: 3.0)
let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
if twoThree == anotherTwoThree {
    print("These two vectors are equivalent.")
}
// Prints "These two vectors are equivalent."

5. Custom Operators

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
prefix operator +++

extension Vector2D {
    static prefix func +++ (vector: inout Vector2D) -> Vector2D {
        vector += vector
        return vector
    }
}

var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
let afterDoubling = +++toBeDoubled
// toBeDoubled now has values of (2.0, 8.0)
// afterDoubling also has values of (2.0, 8.0)

๐Ÿ“• prefix, infix, postfix ํ‚ค์›Œ๋“œ ์‚ฌ์šฉ

  • infix ์˜ ๊ฒฝ์šฐ precedencegroup ํ‚ค์›Œ๋“œ๋กœ ์šฐ์„ ์ˆœ์œ„ ๊ทธ๋ฃน์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ช…์‹œ ์•ˆํ•˜๋ฉด DefaultPrecedence ๋ฅผ ๊ฐ€์ง.
  • ํ•ด๋‹น ๊ทธ๋ฃน์—๋Š” higerThan, lowerThan (์šฐ์„ ์ˆœ์œ„ ๊ด€๋ จ)
  • associativity (๊ฒฐํ•ฉ ๋ฐฉํ–ฅ left, right, none)
  • assignment (์˜ต์…”๋„ ์ฒด์ด๋‹ ์‹œ, ์–ด๋Š ์ชฝ ๋ถ€ํ„ฐ ์ฒด์ด๋‹์„ ํ•˜๋Š”์ง€ - true : associativity ์™€ ๋™์ผํ•œ ๋ฐฉํ–ฅ / false, ๋ช…์‹œ ์•ˆํ•จ : ์™ผ์ชฝ๋ถ€ํ„ฐ ์˜ต์…”๋„ ์ฒด์ด๋‹)
prefix operator **

prefix func ** (value: Int) -> Int {
    return value * value
}

**5 // 25
  • ๋ณดํ†ต์€ ์ด๋Ÿฐ ๊ด‘๋ฒ”์œ„ํ•œ ์ˆซ์ž ์—ฐ์‚ฐ์ž๋ณด๋‹ค, ํด๋ž˜์Šค๋‚˜ ๊ตฌ์กฐ์ฒด ์•ˆ์— static func ๋กœ ๊ตฌํ˜„ํ•˜์—ฌ, ํ•ด๋‹น ํด๋ž˜์Šค๋ผ๋ฆฌ, ๊ตฌ์กฐ์ฒด๋ผ๋ฆฌ ์—ฐ์‚ฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ปค์Šคํ…€ ํ•œ๋‹ค.

Custom Infix Operator ์˜ ์šฐ์„ ์ˆœ์œ„

  • ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ์ค‘์œ„ ์—ฐ์‚ฐ์ž๋Š” ๊ฐ ์šฐ์„ ์ˆœ์œ„ ๊ทธ๋ฃน์— ์†ํ•ด์žˆ๋‹ค.
  • ํ•ด๋‹น ์—ฐ์‚ฐ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ƒ๋Œ€์ ์ธ ์šฐ์„ ์ˆœ์œ„์™€ ์—ฐ์‚ฐ์ž์™€์˜ ์—ฐ๊ด€์„ฑ์„ ์ง€์ •ํ•œ๋‹ค.
  • ์šฐ์„ ์ˆœ์œ„ ๊ทธ๋ฃน์— ๋ช…์‹œ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์‚ผํ•ญ ์กฐ๊ฑด ์—ฐ์‚ฐ์ž๋ณด๋‹ค ํ•˜๋‚˜ ๋†’์€ ์šฐ์„ ์ˆ˜๋ˆ„์ด๊ฐ€ ์ œ๊ณต๋œ๋‹ค.
// +- ๋Š” +  -  ๋ฅผ ์“ฐ๋‹ˆ๊นŒ ๊ทธ๊ฒƒ๊ณผ ๊ฐ™์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„๋‹ค.
infix operator +-: AdditionPrecedence
extension Vector2D {
    static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y - right.y)
    }
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector is a Vector2D instance with values of (4.0, -2.0)

NOTE : ์ ‘๋‘์‚ฌ, ์ ‘๋ฏธ์‚ฌ ์—ฐ์‚ฐ์ž๋Š” ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ง€์ •ํ•˜์ง„ ์•Š์ง€๋งŒ, ๊ฐ™์€ ํ”ผ์—ฐ์‚ฐ์ž์— ์ ‘๋‘ ์ ‘๋ฏธ๊ฐ€ ๋‹ค ๋ถ™์œผ๋ฉด ์ ‘๋ฏธ์‚ฌ๊ฐ€ ๋จผ์ € ์ ์šฉ๋œ๋‹ค.


6. ๊ฒฐ๊ณผ ๋นŒ๋”

  • ๋ฆฌ์ŠคํŠธ๋‚˜ ํŠธ๋ฆฌ ๊ฐ™์€ ์ค‘์ฒฉ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์„ ์–ธํ˜•์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • if for ๊ฐ™์€ ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
protocol Drawable {
    func draw() -> String
}
struct Line: Drawable {
    var elements: [Drawable]
    func draw() -> String {
        return elements.map { $0.draw() }.joined(separator: "")
    }
}
struct Text: Drawable {
    var content: String
    init(_ content: String) { self.content = content }
    func draw() -> String { return content }
}
struct Space: Drawable {
    func draw() -> String { return " " }
}
struct Stars: Drawable {
    var length: Int
    func draw() -> String { return String(repeating: "*", count: length) }
}
struct AllCaps: Drawable {
    var content: Drawable
    func draw() -> String { return content.draw().uppercased() }
}


let name: String? = "Ravi Patel"
let manualDrawing = Line(elements: [
    Stars(length: 3),
    Text("Hello"),
    Space(),
    AllCaps(content: Text((name ?? "World") + "!")), // ์–ด์šฐ ๋ณต์žกํ•ด... ResultBuilder ๋ฅผ ์‚ฌ์šฉํ•˜์ž.
    Stars(length: 2),
    ])
print(manualDrawing.draw())
// Prints "***Hello RAVI PATEL!**"

@resultBuilder ๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์„œ ๊ตฌ์กฐ์ฒด๋ฅผ ์„ ์–ธํ•œ๋‹ค.

@resultBuilder
struct DrawingBuilder {
    static func buildBlock(_ components: Drawable...) -> Drawable {
        return Line(elements: components)
    }
    static func buildEither(first: Drawable) -> Drawable {
        return first
    }
    static func buildEither(second: Drawable) -> Drawable {
        return second
    }
}
  • DrawingBuilder ๋ผ๋Š” ๋นŒ๋”๋กœ ํด๋กœ์ € ์ธ์ž๋ฅผ ๋„˜๊ฒจ์ฃผ์–ด์„œ, ํ•ด๋‹น ํด๋กœ์ € (() -> Drawable)๋ฅผ ์‹คํ–‰ํ•ด์„œ Drawable ์„ return ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค.
  • ์ด์ œ ์‹คํ–‰ํ•  ๋•Œ, Drawable ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํด๋กœ์ €๋ฅผ ๋„˜๊ฒจ์„œ Drawable ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.
func draw(@DrawingBuilder content: () -> Drawable) -> Drawable {
    return content()
}
func caps(@DrawingBuilder content: () -> Drawable) -> Drawable {
    return AllCaps(content: content())
}

func makeGreeting(for name: String? = nil) -> Drawable {
    let greeting = draw {
        Stars(length: 3)
        Text("Hello")
        Space()
        caps {
            if let name = name {
                Text(name + "!")
            } else {
                Text("World!")
            }
        }
        Stars(length: 2)
    }
    return greeting
}
let genericGreeting = makeGreeting()
print(genericGreeting.draw())
// Prints "***Hello WORLD!**"

let personalGreeting = makeGreeting(for: "Ravi Patel")
print(personalGreeting.draw())
// Prints "***Hello RAVI PATEL!**"

if-else ์—์„œ ๊ฐ๊ฐ DrawingBuilder ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

let capsDrawing = caps {
    let partialDrawing: Drawable
    if let name = name {
        let text = Text(name + "!")
        partialDrawing = DrawingBuilder.buildEither(first: text)
    } else {
        let text = Text("World!")
        partialDrawing = DrawingBuilder.buildEither(second: text)
    }
    return partialDrawing
}
extension DrawingBuilder {
    static func buildArray(_ components: [Drawable]) -> Drawable {
        return Line(elements: components)
    }
}
let manyStars = draw {
    Text("Stars:")
    for length in 1...3 {
        Space()
        Stars(length: length)
    }
}

for ๋ฌธ ์ง€์›๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

extension DrawingBuilder {
    static func buildArray(_ components: [Drawable]) -> Drawable {
        return Line(elements: components)
    }
}
let manyStars = draw {
    Text("Stars:")
    for length in 1...3 {
        Space()
        Stars(length: length)
    }
}

์–ด๋–ป๊ฒŒ ๋ณ€ํ™˜๋˜๋Š”์ง€๋Š” ์—ฌ๊ธฐ



์ฐธ๊ณ 
https://bbiguduk.gitbook.io/swift/language-guide-1/advanced-operators

profile
0๋…„์ฐจ iOS ๊ฐœ๋ฐœ์ž์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€