λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ₯– Bread Basics/Swift

Swift 곡식 λ¬Έμ„œ 정리 - ν•¨μˆ˜ (Functions)

by BreadDev 2025. 4. 11.
728x90

μ•ˆλ…•ν•˜μ„Έμš”. μ˜€λŠ˜μ€ ν•¨μˆ˜(Functions)에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€. ν•¨μˆ˜λŠ” νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” μ½”λ“œ λΈ”λ‘μœΌλ‘œ, μ½”λ“œμ˜ μž¬μ‚¬μš©μ„±κ³Ό 가독성을 λ†’μ΄λŠ” 데 맀우 μ€‘μš”ν•©λ‹ˆλ‹€.

πŸ“Œ ν•¨μˆ˜ μ •μ˜μ™€ 호좜

κΈ°λ³Έ ν•¨μˆ˜ μ •μ˜

Swiftμ—μ„œ ν•¨μˆ˜λŠ” func ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •μ˜ν•©λ‹ˆλ‹€:

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}

μ—¬κΈ°μ„œ:

  • func: ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ” ν‚€μ›Œλ“œ
  • greet(person:): ν•¨μˆ˜ 이름과 νŒŒλΌλ―Έν„° λ ˆμ΄λΈ”
  • -> String: λ°˜ν™˜ νƒ€μž…
  • return: ν•¨μˆ˜κ°€ 값을 λ°˜ν™˜ν•˜λŠ” ν‚€μ›Œλ“œ

ν•¨μˆ˜ 호좜

ν•¨μˆ˜λŠ” 이름과 μ μ ˆν•œ 인수(arguments)λ₯Ό μ‚¬μš©ν•˜μ—¬ ν˜ΈμΆœν•©λ‹ˆλ‹€:

print(greet(person: "Anna"))
// "Hello, Anna!" 좜λ ₯

ν•¨μˆ˜(Function): νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 독립적인 μ½”λ“œ 블둝

νŒŒλΌλ―Έν„°(Parameter): ν•¨μˆ˜ μ •μ˜ μ‹œ μ‚¬μš©λ˜λŠ” μž…λ ₯ κ°’μ˜ 이름

인수(Argument): ν•¨μˆ˜ 호좜 μ‹œ μ „λ‹¬ν•˜λŠ” μ‹€μ œ κ°’

πŸ“Œ ν•¨μˆ˜ νŒŒλΌλ―Έν„°μ™€ λ°˜ν™˜κ°’

Swift ν•¨μˆ˜λŠ” νŒŒλΌλ―Έν„°μ™€ λ°˜ν™˜κ°’μ˜ μ‚¬μš©μ΄ 맀우 μœ μ—°ν•©λ‹ˆλ‹€.

νŒŒλΌλ―Έν„° μ—†λŠ” ν•¨μˆ˜

func sayHelloWorld() -> String {
    return "hello, world"
}
print(sayHelloWorld())  // "hello, world" 좜λ ₯

μ—¬λŸ¬ νŒŒλΌλ―Έν„°λ₯Ό κ°€μ§„ ν•¨μˆ˜

func greet(person: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return greetAgain(person: person)
    } else {
        return greet(person: person)
    }
}
print(greet(person: "Tim", alreadyGreeted: true))

λ°˜ν™˜κ°’ μ—†λŠ” ν•¨μˆ˜

func greet(person: String) {
    print("Hello, \(person)!")
}
greet(person: "Dave")  // "Hello, Dave!" 좜λ ₯

void λ°˜ν™˜ νƒ€μž…: ν•¨μˆ˜κ°€ 값을 λ°˜ν™˜ν•˜μ§€ μ•Šμ„ λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€(Swiftμ—μ„œλŠ” () λ˜λŠ” Void둜 ν‘œν˜„).

μ—¬λŸ¬ 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜

νŠœν”Œμ„ μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ 값을 ν•¨κ»˜ λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

func minMax(array: [Int]) -> (min: Int, max: Int) {
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1..<array.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("μ΅œμ†Œκ°’μ€ \(bounds.min), μ΅œλŒ€κ°’μ€ \(bounds.max)")
// "μ΅œμ†Œκ°’μ€ -6, μ΅œλŒ€κ°’μ€ 109" 좜λ ₯

νŠœν”Œ(Tuple): μ—¬λŸ¬ 값을 ν•˜λ‚˜μ˜ 볡합 κ°’μœΌλ‘œ κ·Έλ£Ήν™”ν•˜λŠ” 방법

μ˜΅μ…”λ„ νŠœν”Œ λ°˜ν™˜ νƒ€μž…

전체 νŠœν”Œμ΄ nil일 수 μžˆλŠ” 경우, μ˜΅μ…”λ„ νŠœν”Œ λ°˜ν™˜ νƒ€μž…μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

func minMax(array: [Int]) -> (min: Int, max: Int)? {
    if array.isEmpty { return nil }
    var currentMin = array[0]
    var currentMax = array[0]
    // ... κ΅¬ν˜„ λ‚΄μš© μƒλž΅ ...
    return (currentMin, currentMax)
}

if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
    print("μ΅œμ†Œκ°’μ€ \(bounds.min), μ΅œλŒ€κ°’μ€ \(bounds.max)")
}

μ˜΅μ…”λ„ νŠœν”Œ: 전체 νŠœν”Œμ΄ nil일 수 μžˆμŒμ„ λ‚˜νƒ€λ‚΄λŠ” νƒ€μž… ((Type1, Type2)?)

μ•”μ‹œμ  λ°˜ν™˜μ„ κ°€μ§„ ν•¨μˆ˜

ν•¨μˆ˜ 본문이 단일 ν‘œν˜„μ‹μΈ 경우, return ν‚€μ›Œλ“œλ₯Ό μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

func greeting(for person: String) -> String {
    "Hello, " + person + "!"
}

μ•”μ‹œμ  λ°˜ν™˜(Implicit Return): 단일 ν‘œν˜„μ‹μœΌλ‘œ κ΅¬μ„±λœ ν•¨μˆ˜μ—μ„œ return ν‚€μ›Œλ“œλ₯Ό μƒλž΅ν•  수 μžˆλŠ” κΈ°λŠ₯

πŸ“Œ ν•¨μˆ˜ 인수 λ ˆμ΄λΈ”κ³Ό νŒŒλΌλ―Έν„° 이름

Swift ν•¨μˆ˜λŠ” 인수 λ ˆμ΄λΈ”(argument label)κ³Ό νŒŒλΌλ―Έν„° 이름(parameter name)을 λͺ¨λ‘ κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

인수 λ ˆμ΄λΈ”κ³Ό νŒŒλΌλ―Έν„° 이름

func someFunction(argumentLabel parameterName: Int) {
    // ν•¨μˆ˜ λ‚΄μ—μ„œλŠ” parameterName으둜 μ ‘κ·Ό
}
// 호좜 μ‹œμ—λŠ” argumentLabel μ‚¬μš©
someFunction(argumentLabel: 1)

인수 λ ˆμ΄λΈ” μ§€μ •ν•˜κΈ°

func greet(person: String, from hometown: String) -> String {
    return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
// "Hello Bill! Glad you could visit from Cupertino." 좜λ ₯

인수 λ ˆμ΄λΈ”(Argument Label): ν•¨μˆ˜ 호좜 μ‹œ μ‚¬μš©λ˜λŠ” 이름

νŒŒλΌλ―Έν„° 이름(Parameter Name): ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš©λ˜λŠ” 이름

인자 λ ˆμ΄λΈ” μƒλž΅ν•˜κΈ°

언더바(_)λ₯Ό μ‚¬μš©ν•˜μ—¬ 인수 λ ˆμ΄λΈ”μ„ μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
    // ν•¨μˆ˜ κ΅¬ν˜„
}
someFunction(1, secondParameterName: 2)

πŸ“Œ νŒŒλΌλ―Έν„° κΈ°λ³Έκ°’

νŒŒλΌλ―Έν„°μ— 기본값을 μ§€μ •ν•  수 μžˆμ–΄ 호좜 μ‹œ ν•΄λ‹Ή 인수λ₯Ό μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    // ν•¨μˆ˜ κ΅¬ν˜„
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6)  // parameterWithDefaultλŠ” 6
someFunction(parameterWithoutDefault: 4)  // parameterWithDefaultλŠ” 12 (κΈ°λ³Έκ°’ μ‚¬μš©)

κΈ°λ³Έ νŒŒλΌλ―Έν„° κ°’(Default Parameter Value): μΈμˆ˜κ°€ μ œκ³΅λ˜μ§€ μ•Šμ„ λ•Œ μ‚¬μš©λ˜λŠ” κΈ°λ³Έκ°’

πŸ“Œ κ°€λ³€ νŒŒλΌλ―Έν„°

κ°€λ³€ νŒŒλΌλ―Έν„°(variadic parameter)λŠ” 0개 μ΄μƒμ˜ νŠΉμ • νƒ€μž… 값을 ν—ˆμš©ν•©λ‹ˆλ‹€:

func arithmeticMean(_ numbers: Double...) -> Double {
    var total = 0.0
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}

arithmeticMean(1, 2, 3, 4, 5)  // 3.0 λ°˜ν™˜
arithmeticMean(3, 8.25, 18.75)  // 10.0 λ°˜ν™˜

κ°€λ³€ νŒŒλΌλ―Έν„°(Variadic Parameter): ν•¨μˆ˜ 호좜 μ‹œ μ—¬λŸ¬ 개의 인수λ₯Ό 받을 수 μžˆλŠ” νŒŒλΌλ―Έν„°λ‘œ, νƒ€μž… 뒀에 ...을 λΆ™μ—¬ ν‘œμ‹œν•©λ‹ˆλ‹€.

πŸ“Œ In-Out νŒŒλΌλ―Έν„°

ν•¨μˆ˜κ°€ νŒŒλΌλ―Έν„° 값을 μˆ˜μ •ν•˜κ³  κ·Έ 변경사항을 ν•¨μˆ˜ 호좜이 λλ‚œ 후에도 μœ μ§€ν•˜κ³  싢을 λ•Œ in-out νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€:

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

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someIntλŠ” 이제 \(someInt), anotherIntλŠ” 이제 \(anotherInt)")
// "someIntλŠ” 이제 107, anotherIntλŠ” 이제 3" 좜λ ₯

in-out νŒŒλΌλ―Έν„°: ν•¨μˆ˜ λ‚΄μ—μ„œ μˆ˜μ •λ˜κ³  ν•¨μˆ˜ μ’…λ£Œ 후에도 μˆ˜μ •λœ 값이 μœ μ§€λ˜λŠ” νŒŒλΌλ―Έν„°

&기호: in-out νŒŒλΌλ―Έν„°μ— 인수λ₯Ό 전달할 λ•Œ λ³€μˆ˜ μ•žμ— λΆ™μ΄λŠ” 기호

πŸ“Œ ν•¨μˆ˜ νƒ€μž…

Swiftμ—μ„œ ν•¨μˆ˜λŠ” 자체적인 νƒ€μž…μ„ κ°€μ§€κ³  μžˆμ–΄ λ³€μˆ˜μ— ν• λ‹Ήν•˜κ±°λ‚˜ λ‹€λ₯Έ ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ 전달할 수 μžˆμŠ΅λ‹ˆλ‹€.

ν•¨μˆ˜ νƒ€μž… μ‚¬μš©ν•˜κΈ°

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}

func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
    return a * b
}

var mathFunction: (Int, Int) -> Int = addTwoInts
print("κ²°κ³Ό: \(mathFunction(2, 3))")  // "κ²°κ³Ό: 5" 좜λ ₯

mathFunction = multiplyTwoInts
print("κ²°κ³Ό: \(mathFunction(2, 3))")  // "κ²°κ³Ό: 6" 좜λ ₯

ν•¨μˆ˜ νƒ€μž…(Function Type): ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„° νƒ€μž…κ³Ό λ°˜ν™˜ νƒ€μž…μ„ ν¬ν•¨ν•˜λŠ” νƒ€μž… (예: (Int, Int) -> Int)

νŒŒλΌλ―Έν„° νƒ€μž…μœΌλ‘œ ν•¨μˆ˜ νƒ€μž…

ν•¨μˆ˜λ₯Ό λ‹€λ₯Έ ν•¨μˆ˜μ˜ νŒŒλΌλ―Έν„°λ‘œ 전달할 수 μžˆμŠ΅λ‹ˆλ‹€:

func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
    print("κ²°κ³Ό: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)  // "κ²°κ³Ό: 8" 좜λ ₯

λ°˜ν™˜ νƒ€μž…μœΌλ‘œ ν•¨μˆ˜ νƒ€μž…

ν•¨μˆ˜κ°€ λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€:

func stepForward(_ input: Int) -> Int {
    return input + 1
}

func stepBackward(_ input: Int) -> Int {
    return input - 1
}

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    return backward ? stepBackward : stepForward
}

var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZeroλŠ” 이제 stepBackward() ν•¨μˆ˜λ₯Ό μ°Έμ‘°

while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3... 2... 1... zero! 좜λ ₯

πŸ“Œ 쀑첩 ν•¨μˆ˜

Swiftμ—μ„œλŠ” ν•¨μˆ˜ 내뢀에 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    // 쀑첩 ν•¨μˆ˜ μ •μ˜
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }

    return backward ? stepBackward : stepForward
}

var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZeroλŠ” 이제 μ€‘μ²©λœ stepForward() ν•¨μˆ˜λ₯Ό μ°Έμ‘°

while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4... -3... -2... -1... zero! 좜λ ₯

쀑첩 ν•¨μˆ˜(Nested Function): λ‹€λ₯Έ ν•¨μˆ˜ 내뢀에 μ •μ˜λœ ν•¨μˆ˜λ‘œ, 기본적으둜 μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†μ§€λ§Œ ν¬ν•¨ν•˜λŠ” ν•¨μˆ˜μ— μ˜ν•΄ λ°˜ν™˜λ  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“Œ 정리

Swift의 ν•¨μˆ˜λŠ” 맀우 μœ μ—°ν•˜κ³  κ°•λ ₯ν•œ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€:

  1. 가독성 높은 ν•¨μˆ˜ 호좜: 인수 λ ˆμ΄λΈ”μ„ 톡해 ν•¨μˆ˜ 호좜 μ‹œ 각 인수의 μš©λ„λ₯Ό λͺ…ν™•νžˆ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  2. μœ μ—°ν•œ νŒŒλΌλ―Έν„° μ˜΅μ…˜: κΈ°λ³Έκ°’, κ°€λ³€ νŒŒλΌλ―Έν„°, in-out νŒŒλΌλ―Έν„° λ“± λ‹€μ–‘ν•œ νŒŒλΌλ―Έν„° μ˜΅μ…˜μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
  3. 일급 μ‹œλ―ΌμœΌλ‘œμ„œμ˜ ν•¨μˆ˜: ν•¨μˆ˜λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•˜κ±°λ‚˜, νŒŒλΌλ―Έν„°λ‘œ μ „λ‹¬ν•˜κ±°λ‚˜, λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  4. 쀑첩 ν•¨μˆ˜: ν•¨μˆ˜ 내뢀에 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜μ—¬ μ½”λ“œμ˜ μΊ‘μŠν™”μ™€ μž¬μ‚¬μš©μ„±μ„ 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ κΈ°λŠ₯듀을 적절히 ν™œμš©ν•˜λ©΄ 더 읽기 쉽고 μœ μ§€λ³΄μˆ˜κ°€ μš©μ΄ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 특히 ν•¨μˆ˜ νƒ€μž…κ³Ό 쀑첩 ν•¨μˆ˜λŠ” Swift의 ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° νŠΉμ„±μ„ 잘 λ³΄μ—¬μ£ΌλŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€.