본문 바로가기
Xcode/Swift - PlayGround

PlayGround) 참조값으로 받을 수 있는 함수와 클로저의 놀라운 기능!

by 후르륵짭짭 2021. 1. 14.
728x90
반응형

안녕하세요 후르륵짭짭입니다.

오늘 클로저의 새로운 기능을 배웠습니다.

클로저는 진짜로 기능이 몇개인지 모르겠습니다 ㅎㅎㅎ

 

** 참조값으로 받을 수 있는 Closure **

클로저도 하나의 함수이니, 함수의 기능이라고 보셔도 됩니다.

이 기능을 알아보고 전에,,, 우리가 알면 좋은 것이 있습니다.

바로 변수의 기능인데요.

let number = 10

만약에 우리가 위와 같이 코드를 적었다면 number에 10의 값이 들어 간 겁니다.

그리고 이 number에 주소값이 생성이 됩니다. (예를들어 0x00001 이라고 합시다.)

이렇게 0x00001에 number가 생성 됐기 때문에 어디서든 이 number라는 숫자를 사용 할 수 있습니다.

이 내용을 이해 했다면 이제 제가 설명 하는 것도 이해가 될 겁니다.

 

func makeIncrement(_ number : Int) -> (()->(Int)) {
    
    var runningTotal : Int = 0
    
    func increseFunc() -> Int {
    
        runningTotal += number
        
        return runningTotal
        
    }
    
    return increseFunc
}

만약에 이렇게 이중 중첩으로 함수를 만들었다고 합시다.

그리고 반환 값이 increseFunc 입니다.

 

 - 참고 사항 -

 여기서 increseFunc 와 increseFunc()의 차이를 알아야 합니다

func whatisThis() -> Int{

    return 3
}

만약 이런 함수가 있다고 할 때,

let A = whatisThis

// A의 타입
let A: () -> Int

A의 타입은 () -> Int 로 함수 타입으로 받게 됩니다. 

그러니깐! Int로 받는게 아니라 콜로저 형태로 받는 겁니다!! 

let B = whatisThis()

// B의 타입
let B: Int

반면에 이렇게 whatisThis() 로 해준다면 함수를 실행 시킨다는 의미로

값을 반환하게 되어 B의 타입이 Int로 됩니다.

요약하면 ()은 함수를 실행 시키는 것이고 ()이 없다면 함수 자체를 받는 것 입니다.

 

위의 내용이 이해가 됐다면 increseFunc 로 해준 것은 함수 정의를 보내 준 것이 이해가 됐을 겁니다.

//increseFunc가 incrementByTwo에 저장이 됐다.
//값이 저장이 됐다는 것은 runningTotal의 주소와 number가 모두 참조값으로 저장이 된 것이다.
let incrementByTwo = makeIncrement(2)

//따라서 여기서 실행 시켜주면 runningTotal에 number가 저장이 되면서 반환해준다.
//그런데 incrementByTwo가 메모리에서 해제 된 것이 아니기 때문에
//runningTotal은 값이 더 해진 체로 남아 있게 된다.
let first = incrementByTwo()
print(first)
let second = incrementByTwo()
print(second)

//결과
2
4

그리고 이렇게 코드를 적어주면

incrementByTwo 변수에 makeIncrement(2)의 increseFunc의 주소 값이 전달이 됩니다.

increseFunc 주소값에는 runningTotal의 주소 값과 number 모두 가지고 있습니다.

따라서 아래 first 와 second 변수에 2와 4가 찍 힐 수 있는 겁니다.

즉, 변수 값으로 클로저를 받게 된다면, 이 것은 변수 자체에 클로저의 주소값을 가지게 된 것이고

그래서 변수에 클로저가 가지고 있는 모든 내용물을 가지게 된 것입니다.

그래서 0과 0 로 결과가 나오는게 아니라 2와 4로 나오는 것 입니다.

 

또 다른 예시로 

func changeMyName(increase : Int) ->((String)->(String)) {
    
    var number : Int = 0
    
    var myName : String = ""
    
    func makeName(name : String) -> String {
        
        if number % 2 == 0 {
            myName = "I'm \(number) and \(name)"
        }
        else{
            myName = "I'm oddNumber"
        }
        
        number += increase
        
        return myName
        
    }
    
    
    return makeName
    
}

let changeNameFunction = changeMyName(increase: 3)

let Aname = changeNameFunction("Hururuek") //"I'm 0 and Hururuek"
let Bname = changeNameFunction("ChapChap") // "I'm oddNumber"
let Cname = changeNameFunction("Blog") // "I'm 6 and Blog"

이렇게도 가능합니다.

결국 위와 같은 내용이지만,,,

 

지금 까지 클로저의 값 획득을 알아봤습니다.

큰 도움이 됐다면 광고 한번 클릭 해주세요~~ ㅎㅎ

728x90
반응형

댓글