Swift 함수
꼼꼼한 재은씨의 Swift3 기본편을 보며 Swift 문법 내용을 정리한 내용입니다.
함수와 클로저 (Closure)
독립적으로 처리될 수 있는 것을 분리하여 구조화한 객체.
함수의 이점
- 동일 코드가 여러 번 실행될 때, 재작성이 필요가 없다.
- 기능 단위로 함수화하게 되면, 가독성이 좋아진다.
- 유지 보수 차원에서 이점이 있다.
함수의 정의
func
키워드를 사용하여 함수를 정의한다.
1 | /* |
함수의 호출
일반적으로 함수를 호출하듯이 정의된 함수를 호출하여 실행한다.
1 | funcExample(name: "hwiVeloper", age: 28) |
함수 호출 시 사용하는 파라미터 이름과 함수 내부에서 사용하는 파라미터 이름을 다르게 하고 싶다면 다음과 같은 방법을 사용한다.
1 | func funcExample(userName name: String, userAge age: Int) { |
파라미터 이름을 _ (언더바)로 지정하면 함수 호출 시 이름을 생략할 수 있다.
1 | func funcExample(_ name: String) { |
파라미터 기본값을 지정하면 호출 시 생략이 가능하다.
1 | func funcExample(_ name: String, age: Int = 28) { |
...
를 사용하면 개수가 정해지지 않은 파라미터를 받을 수 있다.
1 | func funcExample(_ numbers: Int...) -> Int { |
함수 중첩이 가능하다.
1 | func funcOuter(message: String) -> (String) -> String { |
눈여겨 볼 점은 funcOuter 의 return type이 (String) -> String
이라는 점이다. funcOuter는 funcInner의 String 을 받아서 String으로 return 하는 함수라는 것이다.
같은 예시지만 중첩 내부에서 다수의 파라미터를 받아서 처리하는 경우이다.
1 | func funcOuter(message: String) -> (String, String) -> String { |
기존의 (String) -> String
에서 (String, String) -> String
으로 변화했다. 두 파라미터를 받아 최종적으로 하나로 처리한다는 뜻이다.
함수의 튜플 반환
함수는 여러 개의 값을 반환할 수 있다.
1 | func getIndvInfo() -> (Int, String) { |
클로저 (Closure)
함수를 좀 더 간결하게 짤 수 있게끔 도와주는 개념이다. 클로저는 { }
로 감싸여진 실행 가능한 코드블럭 이다.
위에서 살펴보았던 함수 중첩을 클로저를 사용하여 재구성한다면,
1 | func funcOuter(message: String) -> (String, String) -> String { |
일반적인 함수와는 다르게 함수명이 존재하지 않는다. 허나, 함수와 기능은 동일하게 수행이 가능하다. 파라미터를 받아 return 값을 뱉어낼 수 있다는 점에서 크게 다를 건 없지만, 모양이 다르다. 결국 클로저는 이름 없는 함수 라고 볼 수 있고, 함수는 이름 없는 클로저 라고 볼 수 있다.
클로저는 중괄호( { }
)로 감싸져 있고, 파라미터를 괄호로 감싸서 정의한다. 함수와 동일하게 ->
로 return type을 정의할 수 있다. in
키워드는 파라미터, return type과 실제 클로저 코드를 분리하고 있다.
단순히 비주얼적으로 본다면 이걸 왜 쓰나 하는 생각이 들 수 있다.
사실 클로저의 장점은 간결함 과 유연함 이다. 이제, 생략 가능한 요소들을 제거해보자.
1 | func funcOuter(message: String) -> (String, String) -> String { |
매우 간결해졌다. 이미 funcOuter에서 정의한 중첩된 내부 함수의 타입이 선언이 되었으므로, 내부에서는 다시 한 번 타입을 정의해 줄 필요가 없는 것이다. return type 역시 마찬가지로 funcOuter에서 정의해주었기 때문에 생략된 것이다.
swift 클로저를 알게 되면서 더욱 놀라웠던 점은 여기서 더 생략이 가능하다는 것이다. 위 코드에서 더 생략한 결과이다.
1 | func funcOuter(message: String) -> (String, String) -> String { |
이제서야 클로저를 쓰는 의미가 보인다. 타이핑해야 할 코드의 양이 줄어들었다.
클로저는 또한 변수처럼 정의가 가능하다.
1 | let funcOuter: (String, String) -> String = { $1 + $0 + ", hello!" } |
옵셔널로도 정의가 가능하다.
1 | let funcOuter: ((String, String) -> String)? |
클로저를 변수로 정의하고 함수에서 return이 가능하듯이, 파라미터로 역시 받을 수 있다.
1 | func closureExample(number: Int, using block: Int -> Int) -> Int { |
클로저 활용하기
- sort()
- filter()
- map()
- reduce()
1 | let numbers = [1, 3, 2, 6, 7, 5, 8, 4] |
install_url
to use ShareThis. Please set it in _config.yml
.