Inout Parameter - ehrldyd15/Swift_Skills GitHub Wiki

Inout Parameter

inout Parameter

Swift์—์„œ ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฉ”ํ„ฐ๋Š” ์ƒ์ˆ˜์ด๋ฏ€๋กœ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ํŒŒ๋ผ๋ฉ”ํ„ฐ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.

๋งŒ์•ฝ ํ•จ์ˆ˜์—์„œ ํŒŒ๋ผ๋ฉ”ํ„ฐ์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ , ๋ณ€๊ฒฝ๋œ ๊ฐ’์ด ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด ์ข…๋ฃŒ๋œ ํ›„์—๋„ ์ง€์†๋˜๊ธธ ์›ํ•œ๋‹ค๋ฉด

inout ํŒŒ๋ผ๋ฉ”ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

inout ํŒŒ๋ผ๋ฉ”ํ„ฐ๋Š” ํ•จ์ˆ˜ ์ •์˜์‹œ ํŒŒ๋ผ๋ฉ”ํ„ฐ์˜ ํƒ€์ž… ์ „์— inout ํ‚ค์›Œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

inout ํŒŒ๋ผ๋ฉ”ํ„ฐ๋Š” ๋ณ€์ˆ˜๋งŒ์„ ์ทจ๊ธ‰ํ•˜๋ฉฐ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ๋•Œ &๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ๊ฐ’์ด ํ•จ์ˆ˜๋‚ด๋ถ€์—์„œ ๋ณ€๊ฒฝ๋  ๊ฒƒ์ž„์„ ๋‚˜ํƒ€๋‚ด์•ผ ํ•œ๋‹ค.

    func swapTwoInts(_ a: inout Int, _ b: inout Int) {
        let temp = a
        a = b
        b = temp
    }

    var someInt = 3
    var anotherInt = 107
    swapTwoInts(&someInt, &anotherInt)

    print("someInt: ", someInt) // 107
    print("anotherInt: ", anotherInt) // 3

inout์˜ ์›๋ฆฌ

inout ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์Œ์˜ ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค.

  • ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„˜๊ฒจ์ง„ ๋ณ€์ˆ˜๊ฐ€ ๋ณต์‚ฌ๋œ๋‹ค.

  • ํ•จ์ˆ˜ ๋ชธ์ฒด์—์„œ, ๋ณต์‚ฌํ•œ ๊ฐ’์„ ์ˆ˜์ •ํ•œ๋‹ค.

  • ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜๋  ๋•Œ, ๋ณ€ํ™”๋œ ๊ฐ’์„ ์›๋ณธ ๋ณ€์ˆ˜์— ์žฌํ• ๋‹นํ•œ๋‹ค.

์ด ๋™์ž‘์„ copy-in copy-out ํ˜น์€ call by value result ๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ inout์€ ์‹ค์ œ๋กœ copy-in copy-out์˜ ์ค„์ž„๋ง์ด๋‹ค.

in-out ์ตœ์ ํ™”

Swift๋Š” inoutํŒŒ๋ผ๋ฉ”ํ„ฐ์— ๋Œ€ํ•œ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ๊ฐ’์„ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ’์ด ์ €์žฅ๋œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๊ฐ’์„ ํ•จ์ˆ˜ ๋‚ด, ์™ธ๋ถ€์—์„œ ์‚ฌ์šฉํ•œ๋‹ค.

์ด ์ตœ์ €๊ธฐํ™”๋ฅผ call by reference๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ณต์‚ฌ๋กœ ์ธํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

inout์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋”ฐ๋กœ ์ตœ์ ํ™”๋ฅผ ๊ณ ๋ คํ•  ํ•„์š”๋Š” ์—†๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ

inout์„ ์‚ฌ์šฉํ•  ๋–„๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผ์— ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ stepSize์™€ number๋Š” ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ๊ธฐ, ์“ฐ๊ธฐ๊ฐ€ ๋™์‹œ์— ์ด๋ฃจ์–ด์ ธ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

    var stepSize = 1

    func increment(_ number: inout Int) {
        number += stepSize
    }

    increment(&stepSize)
    โŒ // Error: conflicting accesses to stepSize

inout ํŒŒ๋ผ๋ฉ”ํ„ฐ๋ฅผ ์บก์ณํ•  ์ˆ˜ ์žˆ๋Š” ํด๋กœ์ €, ์ค‘์ฒฉ ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ nonescaping์ด์—ฌ์•ผ ํ•œ๋‹ค.

inout ํŒŒ๋ผ๋ฉ”ํ„ฐ๋ฅผ ์บก์ณํ•˜๊ธธ ์›ํ•œ๋‹ค๋ฉด, ๋ฐ˜๋“œ์‹œ ์บก์ณ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ถˆ๋ณ€๊ฐ’์œผ๋กœ ๋ช…์‹œํ•ด์•ผํ•œ๋‹ค.

    func someFunction(a: inout Int) -> () -> Int {
        return { [a] in return a + 1 }
    }

๋งŒ์•ฝ ๊ฐ’์„ ์บก์ณํ•˜๊ณ , ๋ณ€๊ฒฝ์‹œํ‚ค๊ธธ ์›ํ•œ๋‹ค๋ฉด local copy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ copy-in copy-out์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์ฝ”๋“œ์—์„œ ๋ชจ๋“  ๋ณ€๊ฒฝ์ด ํ•จ์ˆ˜ ๋ฐ˜ํ™˜ ์ „์— ๋๋‚˜์•ผํ•จ์„ ๋ณด์žฅํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ๋‹ค.

    func multithreadedFunction(queue: DispatchQueue, x: inout Int) {
        // Make a local copy and manually copy it back.
        var localX = x
        defer { x = localX }

        // Operate on localX asynchronously, then wait before returning.
        queue.async { someMutatingOperation(&localX) }
        queue.sync {}
    }

์ฐธ๊ณ ์ž๋ฃŒ

https://hyunsikwon.github.io/swift/Swift-Inout-01/