named closure, unnamed closure 두 가지가 있다.
이름이 붙여진 클로저는 함수라고 부르지만 사실 함수도 클로저인 것이다.
보통은 이름 없는 클로저를 클로저라고 부르긴 함!
클로저도 함수이기 때문에 1급 객체 함수의 특성을 가지고 있다.
func changeName(human: Human) {
human.name = "Somaker"
}
let sodeul = Human.init(name: "Sodeul", age: 10)
changeName(human: sodeul)
print(sodeul.name)
일급객체의 조건은
1. 변수나 상수에 함수를 대입할 수 있어야한다.
- 함수 이름으로 대입하기
```swift
func sayHello(_ name: String) {}
let f = sayHello
```
함수 이름으로 대입할 경우 문제점은 함수가 오버로딩된 경우에 어떤 함수를 말하는 지 몰라서 컴파일 에러가 뜬다.
- 타입 어노테이션을 통해 함수 타입 명시하기
func sayHello(_ name: String) {}
func sayHello(_ name: String, _ age: Int) {}
let f: (String) -> () = sayHello
이것두 파라미터 타입, 리턴 타입이 동일한 함수면 함수 타입도 동일해서 에러를 뱉는다.
func sayHello(name: String) {}
func sayHello(_ name: String) {}
let f = sayHello(name:)
f라는 상수에 함수를 대입한 거지 함수의 실행 결과를 대입한 것이 아니어서
f("Sodeul") 이라고 실행해야한다. argument label은 또 사용하면 안된다.
2. 함수의 반환 타입으로 함수를 사용할 수 있다.
```swift
func outer() -> () -> () {
func inner() {
print("inner!")
}
return inner
}
let f = outer()
f() 를 하면 inner! 가 실행된다.
func doSomething(_ callback: () -> ()) {
callback()
}
이렇게 함수를 파라미터로 받을 경우엔 파라미터 타입을 함수 타입으로 작성해줘야한다.
1) 함수 자체를 넘겨주기
```swift
func success() {
print("Success!")
}
doSomething(success)
2) 클로저로 넘겨주기.