본문 바로가기

iOS/Swift

Swift) 함수(Function) 정복하기 (2/3) - inout / 가변 파라미터 / 기본값 / 중첩 함수

 

 

 

안녕하세요 :) 소들입니다

이전 포스팅에서 함수의 개념과 선언, 호출 방법에 대해 다 잡았다면

이번엔 조금 심화 개념?? 을 공부할 거예요!!!

 

혹시 초보자라면,

이전 포스팅을 꼭 보고오시길...!!!

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. 파라미터로 전달되는 Value 타입의 값은 복사된 상수 값이다

 

자, 여기서 중요한 포인트는 두 가지임

 

Value 타입의 값은 복사돼서 전달된다

이때 복사된 값은 상수이다

 

이 두가지에 대해서 설명해보겠음!!!

먼저, Value 타입은 뭐 Int, String 같은 자료형들을 말하는 것임!

우리가 다음과 같이 name이라는 파라미터를 받는 함수를 만들었음

 

 

func sayHello(name: String) { }

 

 

그리고 다음과 같이 "Sodeul"이라는 값을 가진 

 

 

var nameString = "Sodeul"
sayHello(name: name)

 

 

name이란 변수의 값을 함수의 파라미터로 넘겨줬음

그러면 어떤 일이 일어나냐면, sayHello라는 함수가 실행될 당시,

name이란 파라미터의 값인 "Sodeul"을 복사해서 파라미터로 가짐!!

 

따라서 sayHello 함수가 실행되는 도중에 호출한 곳에서 name이란 변수를 바꿔도,

함수 내부엔 전혀 영향을 주지 않음

예로 보여주겠음

 

 

func sayHello(name: String) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        print("Check #2 \(name)"")
    }
}
 
var nameString = "Sodeul"
sayHello(name: name)
name = "Somaker"
print("Check #1 \(name)")
 

 

 

sayHello를 실행 시키고, sayHello 함수가 끝나기 전에

name의 값을 변경했음!!!!

하지만, sayHello는 실행될 당시 name을 복사해서 갖기 때문에,

 

 

 

 

함수 실행 시작 이후 name의 값이 변경되든 말든 상관 없는 것임!!!!!!1

또한 파라미터로 전달될 때 복사된 값은 상수 라고 했기 때문에

 

다음과 같이 함수 내부에서 파라미터로 받은 값을

 

 

 

 

변경해서 사용할 수 없음!!!

 

 

 

 

2. 파라미터로 전달되는 Reference 타입의 값은 참조된다

 

파라미터의 Value Type의 값은 복사된 상수 값이 전달된다는 건 이제 알겠음

그럼 클래스의 인스턴스 같은 Reference 타입은???

 

Reference Type의 값을 파라미터로 전달할 경우, 참조로 전달된다

 

말 그대로, 파라미터로 참조타입을 전달할 경우에는

이땐 복사된 상수 값이 아닌, 전달되는 값의 주소값을 들고 옴!!

 만약 다음과 같이 함수 내부에서 전달된 인스턴스의 프로퍼티를 변경할 경우

 

 

func changeName(human: Human) {
    human.name = "Somaker"
}
 
let sodeul = Human.init(name: "Sodeul", age: 10)
changeName(human: sodeul)
print(sodeul.name)

 

 

실제 호출된 곳 인스턴스의 sodeul의 프로퍼티 값이

 

 

 

 

바뀜! 왜냐? Instance는 Reference 타입이고,

그렇기 때문에 참조에 의한 전달이 되었기 때문임 (복사해서 전달 X)

 

 

 

 

3. In-Out Parameters : Value 타입의 값을 참조로 전달하는 방법

 

우리말론 ㅁㅓ 입출력 파라미터 라고 함!

일단 선언은 다음과 같이 하고,

 

 

 

 

위에 써놓은 말 그대로, Value 타입의 값을 Reference 타입의 값처럼

"참조"로 전달하고 싶을 때 사용하는 파라미터임!!!

 

 

 ① 함수 파라미터 선언할 때 inout 키워드 작성하기 

 

먼저, 입출력 파라미터로 쓰고 싶다면,

파라미터 type 쓰기 전에 inout 키워드를 쓰면 됨!!

 

 

func sayHello(name: inout String) { }

 

 

이런 식으로!!!!! 

 

 

 ② 함수를 호출할 때 Argument 앞에 & 붙여주기 

 

입출력 파라미터의 경우, 참조로 전달하기 때문에

함수 호출할 때 Argument 앞에 &를 붙여주어야 함

(C언어를 조금이라도 알면 익숙할듯?! :))

 

 

sayHello(name: &name)

 

 

이런 식으로!!!  예제로 테스트 해보면,

 

 

func sayHello(name: inout String) {
    name = "Somaker"
}
 
var nameString = "Sodeul"
sayHello(name: &name)
print(name)
 

 

 

name의 값이 sayHello에 의해서

 

 

 

 

 변경된 값으로 나온다 :)

(소메이커는 쇼메 팬이라 그럼)

 

 

+ 참고로 inout 파라미터는 다음에 공부할

파라미터 기본값 설정, 가변 파라미터 등을 지원하지 않음!

 

 

 

 

4. 파라미터에 기본 값 설정하기

 

파라미터는 말이지 기본 값을 가질 수 있음!

어떻게 사용 하냐면,

 

 

 

 

파라미터의 Type 옆에 = (등호)를 넣어서 기본 값을 지정

이렇게 기본 값을 지정할 경우엔

 

파라미터에 기본 값을 설정한 경우,

호출 시 파라미터를 생략해도 된다

 

예제로 보면,

 

 

func sayHello(name: String = "Stranger") {
    print("Hello, \(name)")
}
 

 

 

이런 식으로 =를 통해 기본 값을 설정할 수 있고,

 

 

sayHello()                  //"Hello, Stranger"
sayHello(name: "Sodeul")    //"Hello, Sodeul"

 

 

호출할 때,

파라미터를 지정하지 않으면 기본 값으로 들어가고,

파라미터를 지정해주면 지정한 값으로 들어감!!!!

여기서 중요한 것은,

 

기본 값이 있는 파라미터는 생략이 가능하다!!!!1

 

 

 

 

5. 가변 파라미터

 

가변 파라미터란, 

 

하나의 파라미터가 여러 개의 아규먼트를 받을 때 사용한다

가변 파라미터의 타입은 배열이다

 

정도가 정의임 :) 

일단 선언은 다음과 같이

 

 

 

 

Type ... 을 붙이는 것임!!!!

만약 다음과 같이 가변 파라미터를 가지는 함수를 만들었음

 

 

func printSum(of nums: Int...) { }

 

 

이럴 경우, nums라는 가변 파라미터는

 

 

 

 

Int형 배열이 됨!!!!!

실제로 호출할 땐 어떻게 호출하냐면,

,(comma)를 이용해서 여러 개의 아규먼트를 다음과 같이 나열하는 것임

 

 

printSum(of: 1234)

 

 

이처럼, 가변 파라미터는 ,(comma)를 이용해 여러 아규먼트를 받기 때문에,

가변 파라미터 바로 뒤에 있는 파라미터는 무조건 Argument Label을 가져야 함!!

주의할 점임!!

 

 

 

 

만약 Argument Label을 Wildcard Pattern으로 생략해 버리면,

컴파일러 입장에서 어디까지 ,(comma)가 가변 파라미터의 값인지 알 수 없기 때문에

다음에 오는 파라미터는 꼭 Argument Label을 가져야 한다~~

 

 

 

 

이런 식으로 사용하면 됨 :)

 

또! 주의할 것이라면, 

가변 파라미터는 기본값을 가질 수 없고,

하나의 파라미터에서밖에 사용을 못함!

 

따라서 다음과 같이 파라미터 두 개가 가변 파라미터를 ㄱ ㅏ지면

 

 

 

 

에러가 난답니다...~~~~

 

 

 

 

6. Nested Function (중첩 함수)

 

Nested Function이 무엇이냐면..

Swift에선 함수 안에 함수를 선언할 수 있단 사실..을.. 알고.. 계심?

 

 

func outer() {
    print("outer")
    
    func inner() {
        print("inner")
    }
}

 

 

이런 식으로 outer라는 함수 안inner라는 함수를 선언할 수 있음!!

이렇게

 

다른 함수 안에 포함되어 있는 함수

 

를 바로 Nested Function이라고 함

이때, Nested Function의 Scope자신을 포함하고 있는 함수이기 때문에,

 

 

 

 

outer 함수 내에서 inner 함수를 실행할 순 있지만,

 

 

 

 

outer 함수 외부에선 inner 함수를 실행할 수 없음!!!

근데 만약, outer 함수에서 inner 함수를 Return 할 경우

 

 

func outer() -> () -> () {
    print("outer")
    
    func inner() {
        print("inner")
    }
    
    return inner
}

 

 

이땐 다음과 같이

 

 

let inner = outer()
inner()

 

 

outer 함수 외부에서도 inner 함수를 사용할 수 있음 :)

지금 outer 함수 return 타입에 혼란이 올 수 있지만

다음 편에서 공부할 내용임!!!!

 

또한 inner함수와 outer 함수의 Life Cycle에 대해 다뤄야 하는데,

이는 Closure와 ARC를 다룰 때 하겠음!

 

.

.

.

 

이번엔 약간 심화 개념을 다뤘고,

마지막 편인 다음편에선 좀~~~~더 어려운 개념을 다루고 끝내려 합니다 :)

틀린내용 궁금점은 언제나 환영

 

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday