안녕하세요 :) 🐮🐮입니다
이번 포스팅은 함수 정복하기란 포스팅을 끝내보려고 합니다 ^^;
내용ㅇ ㅣ좀 어려울 수도 있다 생..ㄱ..ㅏㄱ....
이전 포스팅을 천천히 다 읽고 오심을 추..천
모든 포스팅은 편의 말투로 합니다~!!
1. 함수 표기법
먼저 함수 표기법에 대해서 공부를 해보겠음
아니 그전에 함수 표기법이 뭔데 싶겠지만
말 그대로 함수를 표기하는 방법임!!
이 함수 표기법을 보통 어디서 볼 수 있냐면,
애플 문서 있잖음? Apple Documentation에 함수를 검색하다 보면
머 이런 식으로 함수들이 표기되어 있단 말임???
이것들이 바로 함수 표기법이란 것임!!!
또한 다음에 배우겠지만, 변수(상수)에 함수를 대입하기 위해선
이 함수 표기법으로 대입을 해야 정확히 대입할 수 있음!!!
따라서 우린 함수 표기법에 대해 알아야 함니다
자, 함수 표기법에선 오로지 ⭐️ 파라미터⭐️만 표현함!
리턴 타입은 있든 없든 함수 표기법엔 상관없음!!!!!!!!!!
1-1. 파라미터가 있는 함수 표기법
파라미터가 있을 경우,
이런 식으로 표현함!!!!
()괄호 안에 Argument Label을 써주고 옆에 :를 붙여줌
예로 보면,
func sayHello(name: String ) { } // sayHello(name:)
func sayHello(_ name: String ) { } // sayHello(_:)
func sayHello(to name: String) { } // sayHello(to:)
|
만약 _(Wildcard Pattern)으로 Argument Label을 생략했다 하면,
ArgumentLabel 자리에 _를 써주어야 함!
파라미터가 여러 개라면
func sayHello(name: String, age: Int) { } // sayHello(name:age:)
|
요롷게!!! ㅎㅎ
혹시 Argument Label이 뭔지 모른다면 이 포스팅을 보고 오시오...
1-2. 파라미터가 없는 함수 표기법
자, 파라미터가 없을 경우엔
함수 이름만 덩그라니 쓰면 표기법 끝임!!!!
이또한 예로 본다면
func sayHello() { } // sayHello
func sayHelloToSodeul() { } // sayHelloToSodeul
|
이렇게 표기함!! 근데 헷갈릴 수 있는 게
sayHello()
sayHelloToSodeul()
이렇게 표기해야하는 거 아닌가여??할 수도 있지만,
()를 붙이는 것은 파라미터가 없는 함수를 호출하는 것임!!!!!!!
따라서 파라미터가 없을 경우,
함수표기법에선 () 자체를 없애주어야 함!
2. 함수 타입
여러분 Swift에서 함수는 자료형을 갖고 있답니다?????
함수가 웬 자료형이냐 싶겠지만, 함수 또한 자료형을 가지고 있고
이를 함수 타입이라고 함!!
함수 타입은 위와 같이 표현하는데, 여기서 중요한 것은
우리가 함수를 선언할 때 Return Type이 없다면 생략하고 썼지만,
함수 타입에선 Parameter Type이건 Return Type이건 아무 것도 생략해선 안됨!!
이를 유념하며, 함수 타입을 표현하는 방법을 봅시다 :)
2-1. 파라미터가 없는 함수 타입
func sayHello() {}
|
자, 이런 함수의 경우 함수 타입이 어떻게 되는지 봅시다 :)
보는 방법은 Playgorund에서 함수 표기법을 써주시면,
이 함수의 타입은 () -> () 라는 것을 알 수 있음!
왜냐? 파라미터도 없고, 리턴타입도 없기 때문임!!!
(Swift에선 Void 대신 보통 ()로 나타냄)
2-2. 파라미터가 있는 함수 타입
func sayHello(_ name: String) {}
|
자, 이렇게 파라미터가 있을 경우엔 어떤 타입일지 보겠음.
마찬가지로 함수 표기법을 사용해서 보면,
sayHello란 함수의 타입은 (String) -> () 인 것을 알 수 있음
자, 여기서 중요한 거!!!!!
함수 타입에선 Argument Label이건, Parameter Name이고 뭐고 다 필요 없음
단지, 해당 Parameter의 타입만 중요함!!!
따라서 만약 Parameter가 다음과 같이 여러 개라면,
아 이번엔 Return Type도 추가해보겠음
func sayHello(_ name: String, _ age: Int, alias: String) -> String {}
|
함수의 타입은
(String, Int, String) -> String
이렇게 파라미터의 타입만 나열해둔 것임!!
Return 타입또한 위처럼 표시됨
+ 가변 파라미터의 경우 함수 타입은
++ 입출력 파라미터의 경우 함수 타입은
이런 식으로 표현 된답니다...... :D
3. 일급 객체 함수
여러분 Swift는 객체지향 언어인 동시에 함수형 언어임
함수형 언어가 무엇이냐, 함수가 1급 객체로 취급 되어 개짱인 것임
그럼 도대체 일급 객체가 무엇인데 싶겠지? 호호
일급 객체의 조건은 뭐 객체가 런타임에도 생성되어야 하고,
파라미터로 객체를 전달할 수 있고, 반환값으로 객체를 사용할 수 있고 등등 있는데,
그중 함수가 일급 객체가 되기 위해선 다음과 같은 조건들을 만족해야함
3-1. 변수나 상수에 함수를 대입할 수 있어야 한다
일급 객체 함수가 되기 위해선,
변수나 상수에 함수를 대입할 수 있어야 하는데,
먼저, 대입한다는 개념은 함수를 실행해서 결과값을 대입한다는 것이 아님!
함수 자체를 변수나 상수에 대입해서,
해당 변수나 상수가 함수 자체처럼 쓰이는 것을 말함!
변수나 상수를 대입하는 방법이 총 3가지가 있음!!!
① 함수 이름으로 대입하기
func sayHello(_ name: String) {}
let f = sayHello
|
자, 이런 식으로 함수 이름으로 대입할 수도 있음!
(물론 Parameter, Return 값이 없는 함수 표기법 또한 이렇지만)
근데, 이렇게 함수 이름으로 대입할 경우 문제점이 무엇이냐면
sayHello라는 함수가 오버로딩된 경우
func sayHello(_ name: String) {}
func sayHello(_ name: String, _ age: Int) {}
let f = sayHello //error!
|
sayHello라는 이름의 함수가 두 개이기 때문에,
어떤 함수를 말하는 것이냐???는 컴파일에러가 뜸!
따라서 이럴 땐 다른 방법을 사용해야함
② 타입 어노테이션을 통해 함수 타입을 명시해주기
func sayHello(_ name: String) {}
func sayHello(_ name: String, _ age: Int) {}
let f: (String) -> () = sayHello
|
위에서 배운 함수 타입을 이용해서
Type Annotation으로 명시해주는 것임!!!
근데, 함수 타입을 명시해주는 것또한 문제점이 있는데,
func sayHello(name: String) {}
func sayHello(_ name: String) {}
let f: (String) -> () = sayHello //error!
|
이렇게 파라미터 타입 & 리턴 타입이 동일한 함수가 존재할 경우
함수 타입 또한 동일하기 때문에 컴파일러는 또 에러를 뱉음
따라서 이럴 땐 다음 방법을 사용해야 함
③ 함수 표기법을 통해 대입하기
위에서 함수 표기법을 왜 배워야하는지에 대해 말할 때
잠깐 설명했었음
func sayHello(name: String) {}
func sayHello(_ name: String) {}
let f = sayHello(name:)
|
이렇게 sayHello의 함수 표기법을 이용해서 대입하면,
그땐 문제 해결 ~_~
( + Parameter Type, Return Type이 없는 함수가 오버로딩된 경우,
함수 표기법이 아닌 Type Annotation으로 타입을 명시해주어야 함)
.
.
자 함수 대입하는 방법에 대해선 다 배웠음!
근데 헷갈리면 안되는 것이 우린 f라는 상수에 함수를 대입한 것이지,
sayHello라는 실행 결과를 f에 대입한 것이 아님!
따라서, f라는 상수에 저장된 것은 sayHello라는 함수이기 때문에
이 f를 통해서 우리가 저장한 함수를 실행시킬 수 있고, 실행할 때는 다음과 같이 실행함
자, 또 중요한 것!
함수를 저장한 상수 f를 통해 함수를 호출할 땐 Argument Label을 사용하지 않음
왜냐? sayHello라는 함수 자체를 호출할 땐 당연히 Argument Label이 필요하지만,
sayHello를 f라는 상수에 넣는 순간 함수 타입만 가져가지, Argument Label까지 가져가진 않음
만약, 함수를 저장한 상수(변수)를 호출할 때 Argument Label을 사용하면
에러 떠용
3-2. 함수의 반환 타입으로 함수를 사용할 수 있다
func outer() -> () -> () {
func inner() {
print("inner!")
}
return inner
}
|
위에서 보면 outer란 함수가 inner라는 함수를 반환하구 있음!!!!
참고로 리턴할 함수 표기는 함수 대입할 때와 똑같이
함수 이름을 쓰든, 표기법을 쓰든, Annotation을 쓰든 하면 됨!
자 근데 위 함수를 보면 어디서 띠용 하냐면,
() -> () -> ()
????
이부분이 이해가 안 갈거..
자...... 함수를 반환하려면,
"반환 타입"에 반환하려는 "함수 타입"을 작성
해야 한다는 사실을 알아두어야 함
따라서 위 표현식의 의미는
이렇게 이해하면 됨!!!!
첫 번째 괄호는 outer 함수의 파라미터고,
첫 번째 () -> 뒤에 오는 것은 리턴하고자 하는 함수(inner)의 타입임!!!
따라서, 만약 다음과 같이
let f = outer()
f()
|
outer 함수의 리턴 값을 받아서 실행해보면,
inner가 실행이 됨 :)
3-3. 함수의 파라미터로 함수를 전달할 수 있다
자, 마지막임!
보통 파라미터로 함수를 전달하는 것을 어디서 많이 사용하냐면,
콜백함수
에서 사용하는 것임!!!!
예를 들어, 데이터를 fetch 하는 함수를 실행했을 경우,
너 데이터 다 가져왔으면 이 함수 실행시켜줘!
하고, 함수를 파라미터로 전달해 주는 것임
따라서, 보통 클로저를 통해 작성하는데
함수 클로저, 둘 다 봐보겠음
func doSomething(_ callback: () -> ()) {
callback()
}
|
자, 이렇게 함수를 파라미터로 받을 경우,
"파라미터의 타입"을 "함수 타입"으로 작성
해주어야 함!!!!
그럼, 두 가지로 파라미터에 함수를 넘겨줄 수 있는데
① 함수(Named Closure)로 넘겨주기
func success() {
print("Success!")
}
doSomething(success)
|
이렇게 함수 자체를 넘겨줄 수도 있고,
② 클로저(Unnamed Closure)로 넘겨주기
doSomething {
print("Success!")
}
|
이렇게 클로저를 통해 넘겨줄 수도 있음!
(클로저는 다다음쯤에 포스팅 할거임)
아, 참고로 함수를 파라미터로 받은 경우,
파라미터로 받은 함수를 "실행" 해야 하므로,
func doSomething(_ callback: () -> ()) {
callback()
callback()
callback()
}
|
()를 통해서 호출해주어야 함!
그럼 실제 내가 전달한 함수(클로저)가 doSomething 함수에 의해 3번 실행됨
파라미터가 있다면 다음과 같이!!
func doSomething(_ callback: (String) -> ()) {
callback("sodeul")
callback("sodeul")
callback("sodeul")
}
doSomething {message in
print("Success!" + message)
}
|
사용하시면
됩니다 :)
.
.
.
음 내용이 좀 어려웠을 수도 있는데
이제 함수에 대해 기본적인 것은 다 아는 겁니다 :)
다음에 배울 클로저까지 다 이해한다면
Swift 함수 정복 ~~~~🌝🌝🌝
함수 표기법
함수 타입
이 둘을 헷갈리지 말고 꼭 제대로 공부 한다면,
막히는 내용은 없었을 거라 생각합니다 :)
잘못된 내용이나 피드백 환영 🌞🌞
'iOS > Swift' 카테고리의 다른 글
Swift) 클로저(Closure) 정복하기(1/3) - 클로저, 누구냐 넌 (21) | 2020.12.21 |
---|---|
Swift) defer를 알아보자 (11) | 2020.12.16 |
Swift) 함수(Function) 정복하기 (2/3) - inout / 가변 파라미터 / 기본값 / 중첩 함수 (5) | 2020.12.15 |
Swift) 함수(Function) 정복하기 (1/3) - 함수? 메서드? 클로저? (13) | 2020.12.15 |
Swift) Method Swizzling을 알아보자 (3) | 2020.12.14 |