λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

🍎 iOS/Swift

[Swift] ν•¨μˆ˜(Function) - κ³ κΈ‰

728x90

[Contents]

  • ν•¨μˆ˜ Overloading
  • 쀑첩 ν•¨μˆ˜
  • μ’…λ£Œλ˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ (Nonreturning function)
  • λ°˜ν™˜ 값을 λ¬΄μ‹œν•  수 μžˆλŠ” ν•¨μˆ˜ ( @discardableResult 속성 )
  • μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μž (Omitting Argumetn Labels)
  • κ°€λ³€ λ§€κ°œλ³€μˆ˜ (Variadic Parameters)
  • ν•¨μˆ˜ νƒ€μž… (Function Types)

🍎  ν•¨μˆ˜ Overloading

λ¨Όμ € μ˜€λ²„λ‘œλ”©μ΄λž€ 같은 μ΄λ¦„μ˜ ν•¨μˆ˜λ₯Ό μ—¬λŸ¬ 개 μ •μ˜ν•˜κ³  λ§€κ°œλ³€μˆ˜λ₯Ό λ‹€λ₯΄κ²Œ ν•˜μ—¬ λ‹€μ–‘ν•œ μœ ν˜•μ˜ ν˜ΈμΆœμ— 응닡 κ°€λŠ₯ν•˜κ²Œ ν•œλ‹€.

λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…μ΄ λ‹€λ₯΄κ±°λ‚˜ λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜κ°€ λ‹€λ₯΄λ‹€λ©΄ 이름이 같은 ν•¨μˆ˜λ₯Ό μ—¬λŸ¬ 개 λ§Œλ“€ 수 μžˆλ‹€.

func hello(name: Int){ }
func hello(name: String){ }
func hello(name: String, age: Int){ }

λ˜ν•œ, μ „λ‹¬μΈμž λ ˆμ΄λΈ”λ§Œ λ‹€λ₯΄κ²Œ 써주더라도 ν•¨μˆ˜ 쀑볡 μ •μ˜λ‘œ λ™μž‘ κ°€λŠ₯ν•˜λ‹€.

func hello(to name: String, _ age: Int){
    print("hello \(name), your age is \(age)")
}
func hello(to name: String, repeatCounting age: Int){
    print("hello \(name), your age is \(age)")
}

hello(to: "yeon", 2)
hello(to: "yeon", repeatCounting: 3)

🍎  쀑첩 ν•¨μˆ˜

  • ν•¨μˆ˜ μ•ˆμ—μ„œ ν•¨μˆ˜ κ΅¬ν˜„ 및 μ‚¬μš© κ°€λŠ₯
  • μ „μ—­ ν•¨μˆ˜κ°€ λ§Žμ€ ν”„λ‘œκ·Έλž¨μ—μ„œ 쀑첩 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‚¬μš©λ²”μœ„λ₯Ό μ’€ 더 λͺ…ν™•ν•˜κ²Œ ν‘œν˜„ κ°€λŠ₯
typealias UpDownFunc = (Int) -> Int            // νƒ€μž… 별칭

func funcForMove(shouldGoUP: Bool) -> UpDownFunc {    // λ°˜ν™˜ νƒ€μž…μ΄ ν•¨μˆ˜
    func goUp(currentFloor: Int) -> Int {
        return currentFloor + 1
    }
    
    func goDown(currentFloor: Int) -> Int {
        return currentFloor - 1
    }
    
    return shouldGoUP ? goUp : goDown
}

var currentFloor: Int = 10

var targetFloor: Int = 6

let moveToTarget: UpDownFunc = funcForMove(shouldGoUP: currentFloor<targetFloor)

while currentFloor != targetFloor {
    print("ν˜„μž¬ \(currentFloor) μΈ΅...")
    currentFloor = moveToTarget(currentFloor)
}
print("띡! \(currentFloor)μΈ΅ 도착.")
//ν˜„μž¬ 10 μΈ΅...
//ν˜„μž¬ 9 μΈ΅...
//ν˜„μž¬ 8 μΈ΅...
//ν˜„μž¬ 7 μΈ΅...
//띡! 6μΈ΅ 도착.

🍎  μ’…λ£Œλ˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ (Nonreturning function)

  • μ’…λ£Œλ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것은 return λ˜μ§€ μ•Šκ³  λΉ„μ •μƒμ μœΌλ‘œ λλ‚˜λŠ” 것을 의미.
  • 즉, μ’…λ£Œλ˜μ§€ μ•ŠλŠ” ν•¨μˆ˜λŠ” 였λ₯˜λ₯Ό λ˜μ§€κ³  μ€‘λŒ€ν•œ μ‹œμŠ€ν…œ 였λ₯˜λ₯Ό λ³΄κ³ ν•œ ν›„ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œν•˜κΈ° μœ„ν•΄μ„œ 생겨남
  • λΉ„ λ°˜ν™˜ ν•¨μˆ˜λŠ” μ–΄λ””μ„œλ“  호좜이 κ°€λŠ₯ν•˜κ³  λ°˜ν™˜ νƒ€μž…μ„ Never둜 λͺ…μ‹œν•˜μ—¬ μ •μ˜
//μ’…λ£Œλ˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ > Never νƒ€μž… κ°’ λ°˜ν™˜
func myHairFallsOut() -> Never {
    fatalError("Something very, very bad happened")
}

func goodMorning(isAllIsWell: Bool) -> Void {
    guard isAllIsWell else {
        print("OMG!")
        myHairFallsOut()
    }
    print("All is well!")
}

goodMorning(isAllIsWell: true)    //All is well!
goodMorning(isAllIsWell: false)   //OMG!   ν”„λ‘œμ„ΈμŠ€ μ’…λ£Œ ν›„ μ—λŸ¬ λ°œμƒ

[좜λ ₯ ν™”λ©΄]


🍎  λ°˜ν™˜ 값을 λ¬΄μ‹œν•  수 μžˆλŠ” ν•¨μˆ˜ ( @discardableResult 속성 )

  • @discardableResult : Swiftμ—μ„œ λ°œμƒν•˜λŠ” Warning을 λ¬΄μ‹œν•˜λŠ” 속성
  • μ˜λ„μ μœΌλ‘œ ν”„λ‘œκ·Έλž˜λ¨Έκ°€ λ°˜ν™˜ 값을 ν•„μš”ν•˜μ§€ μ•Šμ„ λ•Œ μ»΄νŒŒμΌλŸ¬μ—κ²Œ 미리 μ•Œλ €μ€˜μ„œ κ²½κ³ λ₯Ό 받지 μ•Šκ²Œλ” ν•¨μˆ˜λ₯Ό μž‘μ„± κ°€λŠ₯
  • ν•¨μˆ˜ μ„ μ–Έ μ•žμ— @discardableResult 속성을 적어 μ„ μ–Έ

[warning이 λ°œμƒν•˜λŠ” μ˜ˆμ‹œ]

  • ν•¨μˆ˜μ˜ 리턴 값을 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 경우 Xcode μ»΄νŒŒμΌλŸ¬κ°€ Warning을 λ±‰λŠ”λ‹€.

[@discardableResult μ μš©ν•˜μ—¬ warning 제거]

  • λ°˜ν™˜ 값을 μ‚¬μš©ν•˜μ§€ μ•Šμ„ 수 μžˆλ‹€κ³  미리 μ•Œλ ΈκΈ° λ•Œλ¬Έμ— λ°˜ν™˜ 값을 μ‚¬μš©ν•˜μ§€ μ•Šμ•„λ„ μ»΄νŒŒμΌλŸ¬κ°€ κ²½κ³ ν•˜μ§€ μ•ŠλŠ”λ‹€.


🍎 μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μž (Omitting Argumetn Labels)

μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μžλ₯Ό κ³΅λΆ€ν•˜κΈ° 이전에, swift ν•¨μˆ˜μ˜ μ „λ‹¬μΈμž λ ˆμ΄λΈ”(Argument label) κ°œλ…μ„ μž‘μ•„λ³΄μž.

Swift ν•¨μˆ˜μ—μ„œλŠ” 가독성을 μœ„ν•΄μ„œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ μ‚¬μš©ν•˜λŠ” νŒŒλΌλ―Έν„°(μ™ΈλΆ€νŒŒλΌλ―Έν„°)의 이름과 ν•¨μˆ˜ μ•ˆμ—μ„œ κ΅¬ν˜„λœ νŒŒλΌλ―Έν„°(λ‚΄λΆ€νŒŒλΌλ―Έν„°)의 이름을 ꡬ뢄가λŠ₯ν•˜λ‹€. μ΄λ•Œ 이 μ™ΈλΆ€ νŒŒλΌλ―Έν„°λ₯Ό μ „λ‹¬μΈμž λ ˆμ΄λΈ”μ΄λΌ ν•œλ‹€.

즉, μ™ΈλΆ€νŒŒλΌλ―Έν„° = 전달 인자 λ ˆμ΄λΈ”,

λ‚΄λΆ€νŒŒλΌλ―Έν„° = λ§€κ°œλ³€μˆ˜ 이름

μ΄λ•Œ, μ™ΈλΆ€νŒŒλΌλ―Έν„°λŠ” λ‚΄λΆ€μ—μ„œ μ‚¬μš© λΆˆκ°€ν•˜κ³  λ‚΄λΆ€νŒŒλΌλ―Έν„°λŠ” ν˜ΈμΆœν•  λ•Œ μ‚¬μš©ν•  수 μ—†λ‹€.

//func ν•¨μˆ˜λͺ… (μ™ΈλΆ€νŒŒλΌλ―Έν„° λ‚΄λΆ€νŒŒλΌλ―Έν„°: νƒ€μž…){}
//func ν•¨μˆ˜λͺ… (μ „λ‹¬μΈμžλ ˆμ΄λΈ” λ§€κ°œλ³€μˆ˜μ΄λ¦„: νƒ€μž…){}

func sum(inputNumber number1: Int, number2: Int) -> Int{
    //inputNumber = 1 // inputNumber은 μ™ΈλΆ€νŒŒλΌλ―Έν„°λ‘œ λ‚΄λΆ€μ—μ„œ μ ‘κ·Ό μ•ˆλΌ! ν˜ΈμΆœν•  λ•Œλ§Œ κ°€λŠ₯
    return number1 * number2// λ‚΄λΆ€ νŒŒλΌλ―Έν„° μ‚¬μš©, λ‚΄λΆ€μ—μ„œ 둜직으둜 μ‹€ν–‰ 될 λ•Œ
}

var res = sum(inputNumber: 1, number2: 2) // ν˜ΈμΆœμ‹œ μ™ΈλΆ€ νŒŒλΌλ―Έν„° inputNumber에 κ°’ μž…λ ₯

μ΄λŸ¬ν•œ 전달 인자 λ ˆμ΄λΈ”μ„ μ‚¬μš©ν•˜κ³  싢지 μ•Šλ‹€λ©΄ μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μžλ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.

ν•¨μˆ˜μ„ μ–Έ μ‹œ μ™ΈλΆ€ λ§€κ°œλ³€μˆ˜ μžλ¦¬μ— _(언더바)λ₯Ό μ‚¬μš©ν•˜μ—¬ 인자 λ ˆμ΄λΈ” 없이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

즉, μ™ΈλΆ€νŒŒλΌλ―Έν„° μ‚¬μš©μ„ μƒλž΅ν•˜κ² λ‹€λŠ” μ˜λ―Έμ΄λ‹€.

sumν•¨μˆ˜μ™€ 같은 νŒŒλΌλ―Έν„°κ°€ μœ μΆ”κ°€λŠ₯ν•œ ν•¨μˆ˜μ—μ„œ μ‚¬μš©ν•˜λ©΄ μ’‹λ‹€! 

func sum(_ a : Int , _ b : Int) -> Int{
    return a+b
}
// νŒŒλΌλ―Έν„° 없이 κ°’λ§Œ μž…λ ₯ν•˜μ—¬ ν•¨μˆ˜ 호좜
sum(1, 2)
// >> 3

🍎 κ°€λ³€ λ§€κ°œλ³€μˆ˜ (Variadic Parameters)

Swift ν•¨μˆ˜μ—μ„œλŠ” 가변적인 개수의 νŒŒλΌλ―Έν„°λ₯Ό μž…λ ₯받을 수 μžˆμ–΄ 전달 받을 κ°’μ˜ 개수λ₯Ό μ•ŒκΈ° μ–΄λ €μšΈ λ•Œ μ‚¬μš©ν•  수 μžˆλ‹€.

μ•„λž˜μ™€ 같이 νŒŒλΌλ―Έν„° νƒ€μž…κ³Ό ν•¨κ»˜ "...”을 μž…λ ₯μ‹œ κ°€λ³€μΈμžλ‘œ μΈμ‹λ˜μ–΄ κ°œμˆ˜λ₯Ό μ œν•œν•˜μ§€ μ•Šκ³  μΈμžκ°’μ„ μž…λ ₯λ°›κ³ , μž…λ ₯받은 μΈμžκ°’μ€ λ°°μ—΄μ— μ €μž₯ν•œλ‹€. (κ°€λ³€ λ§€κ°œλ³€μˆ˜λŠ” ν•¨μˆ˜λ‹Ή ν•˜λ‚˜λ§Œ κ°€μ§ˆ 수 μžˆλ‹€.)

//func ν•¨μˆ˜μ΄λ¦„(λ§€κ°œλ³€μˆ˜1이름: λ§€κ°œλ³€μˆ˜1νƒ€μž…, μ „λ‹¬μΈμž λ ˆμ΄λΈ” λ§€κ°œλ³€μˆ˜2이름: λ§€κ°œλ³€μˆ˜2νƒ€μž…...) -> λ°˜ν™˜νƒ€μž… {
//    /* ν•¨μˆ˜ κ΅¬ν˜„λΆ€ */
//    return
//}

// 예) String νƒ€μž…μ˜ friends둜 λΆˆλ¦¬λŠ” λ°°μ—΄λ‘œ λ§Œλ“€μ–΄μ§
func sayHelloToFriends(me: String, friends: String...) -> String {
    return "Hello \(friends)! I'm \(me)!"
}
sayHelloToFriends(me: "yeon", friends: "hana", "eric", "wing")
// >> Hello ["hana", "eric", "wing"]! I'm yeon!

// 예) array > for in 으둜 λ”ν•˜κΈ°, numbers >> Intν˜• array type
func sumAll(numbers: Int...) -> Int{ 
    var total = 0
    for number in numbers{
        total += number
    }
    return total
}

// ν˜ΈμΆœμ‹œ λ§€κ°œλ³€μˆ˜ 값듀은 μ‰Όν‘œλ‘œ κ΅¬λΆ„ν•œλ‹€.
sumAll(numbers: 1,2,3,4)    
// >> 10

🍎 ν•¨μˆ˜ νƒ€μž… (Function Types)

μŠ€μœ„ν”„νŠΈλŠ” ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ° νŒ¨λŸ¬λ‹€μž„μ„ ν¬ν•¨ν•˜λŠ” 닀쀑 νŒ¨λŸ¬λ‹€μž„ μ–Έμ–΄λ‘œ μŠ€μœ„ν”„νŠΈμ˜ ν•¨μˆ˜λŠ” μΌκΈ‰κ°μ²΄μ΄λ―€λ‘œ λ³€μˆ˜, μƒμˆ˜ 등에 μ €μž₯이 κ°€λŠ₯ν•˜κ³  λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 전달할 μˆ˜λ„ μžˆλ‹€.

//(λ§€κ°œλ³€μˆ˜1νƒ€μž…, λ§€κ°œλ³€μˆ˜2νƒ€μž… ...) -> λ°˜ν™˜νƒ€μž…

//ν•¨μˆ˜ νƒ€μž… μ„ μ–Έ
typealias TypeFuction = (Int, Int) -> Int  

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

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

var AddResult: TypeFuction = add
AddResult(1, 2)

var MultiplyResult: TypeFuction = multiply
MultiplyResult(1, 2)


func diffAdd(a: (Int, Int) -> Int) -> Int {
    return 0
}

diffAdd(a: AddResult)
λ°˜μ‘ν˜•