• κΈ°λ³Έ μ—°μ‚°μž 외에도 λΉ„νŠΈ μ—°μ‚°μž 같은 κ³ κΈ‰ μ—°μ‚°μžκ°€ μ œκ³΅λœλ‹€.
  • 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개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보

Powered by GraphCDN, the GraphQL CDN