[Swift] mutating ν‚€μ›Œλ“œ

parkgyurimΒ·2022λ…„ 7μ›” 1일
0

Swift

λͺ©λ‘ 보기
4/8
post-thumbnail
post-custom-banner

🧩 Types in Swift

μš°μ„  Mutating ν‚€μ›Œλ“œ μ—λŒ€ν•΄ μ„€λͺ…ν•˜κΈ° 전에, Swift 의 Type 을 κ°„λž΅ν•˜κ²Œ μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.
Swift 의 λ³€μˆ˜μ—λŠ” Value Type κ³Ό Reference Type 이 μžˆμŠ΅λ‹ˆλ‹€.

Value Type

struct, enum, tuple λ“±

Swift의 κΈ°λ³Έ μžλ£Œν˜• (Int, Float, Double, Bool, String, Array, Dictionary, Set λ“±) 은 struct둜 κ΅¬ν˜„λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€. 즉, Value Type μž…λ‹ˆλ‹€.

Reference Type

class, function(closure) λ“±

차이점

두가지 Type은 Copy ν•  λ•Œ 차이λ₯Ό λ³΄μž…λ‹ˆλ‹€.
볡사, 즉 ν•΄λ‹Ή λ³€μˆ˜λ₯Ό κ°–κ³  μƒˆλ‘œμš΄ λ³€μˆ˜λ₯Ό μƒμ„±ν• λ•Œ,

  • Value Type 은 λ°μ΄ν„°μ˜ μƒˆλ‘œμš΄ 볡사본을 생성 ➑️ κΉŠμ€ 볡사 (Deep Copy)
  • Reference Type 은 원본 데이터λ₯Ό μ°Έμ‘° ➑️ 얕은 볡사 (Shallow Copy)
    λ”°λΌμ„œ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€μ˜ 값을 λ³€κ²½ν•˜λ©΄ 데이터가 μ°Έμ‘°ν•˜κ³  μžˆλŠ” μ›λ³Έμ˜ 데이터도 ν•¨κ»˜ λ³€κ²½λ©λ‹ˆλ‹€.

사싀 Swiftμ—μ„œλŠ” COW (Copy on Write) 기법 을 μ‚¬μš©ν•˜μ—¬, Value Type 의 λ³΅μ‚¬λ³Έμ—μ„œ κ°’ 변경이 이루어 μ‘Œμ„λ•Œ μ‹€μ œ μƒˆλ‘œμš΄ λ©”λͺ¨λ¦¬ 곡간을 ν• λ‹Ήν•˜μ—¬ μ €μž₯을 ν•˜κ²Œ λ©λ‹ˆλ‹€.

(즉, 원본과 볡사본이 λ™μΌν•œ 값을 κ°–κ³  μžˆμ„λ•ŒλŠ” ꡳ이 λ©”λͺ¨λ¦¬ 곡간을 μ‚¬μš©ν•˜μ§€ μ•Šκ² λ‹€λŠ” κ²ƒμž„!)


🦹 mutating

ν•„μš”μ„±

Structures and enumerations are value types. By default, the properties of a value type can’t be modified from within its instance methods.
Swift Documents - Methods

Swift의 Value Type 은 기본적으둜 λ‚΄λΆ€μ—μ„œ μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œλ₯Ό 톡해 λ‚΄λΆ€ 값을 μˆ˜μ •ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

struct Point {
    var x = 0.0, y = 0.0
    func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX // πŸ”₯ ERROR
        y += deltaY // πŸ”₯ ERROR
    }
}

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— λ‚΄λΆ€μ—μ„œ κ°’ 변경이 ν•„μš”ν•  경우, ν•΄λ‹Ή λ©”μ„œλ“œκ°€ mutating λ©”μ„œλ“œλΌλŠ” 것을 λͺ…μ‹œν•˜μ—¬ 값을 λ³€κ²½ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ mutating λ©”μ„œλ“œμ—μ„œλŠ” self λ₯Ό 톡해 μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό ν• λ‹Ήν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš© 방법

λ‚΄λΆ€μ—μ„œ κ°’ λ³€κ²½

μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œμ—μ„œ ꡬ쑰체 λ‚΄λΆ€μ˜ 값을 λ³€κ²½

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0) // β†’ somePoint 의 κ°’ : (3.0, 4.0)

μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€ ν• λ‹Ή

μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œμ—μ„œ self λ₯Ό 톡해 μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€ ν• λ‹Ή

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        self = Point(x: x + deltaX, y: y + deltaY)
    }
}

var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0) // β†’ somePoint 의 κ°’ : (3.0, 4.0)

πŸ“Œ let λ³€μˆ˜

λ‹Ήμ—°ν•œ μ΄μ•ΌκΈ°μ΄κ² μ§€λ§Œ, let 으둜 μ„ μ–Έλœ Value Type은 Mutating λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ”λΌλ„ 값을 λ³€κ²½ν•  수 μ—†μŠ΅λ‹ˆλ‹€!

let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0) // πŸ”₯ ERROR

πŸ‘ 마무리

μ˜€λŠ˜μ€ Swift의 Type κ³Ό Value Type λ‚΄λΆ€ 값을 μˆ˜μ •μ„ κ°€λŠ₯ν•˜κ²Œ ν•΄μ£ΌλŠ” mutating ν‚€μ›Œλ“œ 에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

이제껏 value type κ³Ό reference type 을 κΉŠμ€ 이해없이 κ·Έλƒ₯ κ°’ νƒ€μž…μ€ 그렇지, μ°Έμ‘° νƒ€μž…μ€ 저렇지.. μ΄λ ‡κ²Œ μ‚΄κ³  μžˆμ—ˆλŠ”λ° 이번 포슀트λ₯Ό ν†΅ν•΄μ„œ 이해λ₯Ό ν•˜κ³  λ„˜μ–΄κ°ˆ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. κ²°λ‘ μ μœΌλ‘œλŠ” "value type 은 말 κ·ΈλŒ€λ‘œ λ³€μˆ˜ μžμ²΄κ°€ ν•˜λ‚˜μ˜ κ°’μœΌλ‘œ, μƒμˆ˜μ²˜λŸΌ λ³΄μ—¬μ Έμ„œ 이 값을 λ‚΄λΆ€μ—μ„œ μˆ˜μ •ν•˜κΈ° μœ„ν•΄μ„œλŠ” μΈμŠ€ν„΄μŠ€ λ©”μ„œλ“œ μ•žμ— mutating ν‚€μ›Œλ“œλ₯Ό λΆ™μ—¬μ„œ 이λ₯Ό κ°€λŠ₯ν•˜κ²Œ ν•œλ‹€" 라고 μ΄ν•΄ν•˜λ©΄ 될 것 κ°™μŠ΅λ‹ˆλ‹€!

ν‹€λ¦° 정보 λ˜λŠ” κΆκΈˆν•œ 점이 μžˆλ‹€λ©΄ λŒ“κΈ€ λΆ€νƒλ“œλ¦½λ‹ˆλ‹€! μ½μ–΄μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€β€ΌοΈ

post-custom-banner

0개의 λŒ“κΈ€