함수
스위프트에서 함수는 일급 객체이다.
여기서 일급 객체란, 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다. 함수에 매개변수로 넘기기, 수정하기, 변수에 대입하기와 같은 연산을 지원할 때 일급 객체라고 한다.(feat. wiki)
함수와 메서드
함수와 메서드는 기본적으로 같다. 다만 상황에 따라 다르게 불리는 것인데, 모듈 전체에서 전역적으로 사용이 가능하다면 “함수”, 구조체,클래스,열거형 등 특정 타입에 연관되어 사용하는 함수를 “메서드”라고 부른다.
조건문과 반복문에서와 달리 함수에서는 소괄호(())를 생략할 수 없다!
함수를 정의하는 키워드는 func이다. 파이썬에서는 funtion이었는데 조금 더 짧다.
함수 이름을 지정 후, 매개변수는 소괄호 안에 들어가게 된다. 반환타입 명시시에는 -> 를 사용한다.
반환은 마찬가지로 return을 사용한다. 아래 일반적인 함수 구문을 보자.
func funcName(parameter: Type) -> Type {
print("실행구문 자리")
return "Value"
}
파라미터와, 반환타입에는 알맞는 type을 써주면된다!
아래 예시를 보자.
func gameName(name: String) -> String {
return "이건 \(name)이야"
}
gameName(name: "위닝")
// 이건 위닝이야
함수 사용시에는 return을 생략해도 동일하게 작동한다.
결과값이 함수의 반환 타입과 일치하기만 하면 된다!
func gameName(name: String) -> String {
"이건 \(name)이야"
}
gameName(name: "위닝")
// 이건 위닝이야
매개변수
매개변수는 써줄 수도 있고, 써주지 않을 수도 있다.
매개변수가 없는 함수
func noParam() -> String {
return "noParam works!"
}
noParam()
// "noParam works!"
매개변수가 여러 개인 함
func person(name: String, age: Int) -> String{
return "My Name is \(name) and I'm \(age)"
}
person(name:"Chamin",age:26)
// "My Name is Chamin and I'm 26"
위 함수에서 name은 매개변수 이름(parameter name)이라고 하고, 매개변수 이름 앞에 적어주는 from이나 to같은 경우 전달인자 레이블(argument label)이라고 한다.
func hello(from name:String, to yourName: String) -> String {
return "\(yourName) to \(name)"
}
hello(from: "cha", to: "min")
// "min to cha"
위와 달리 전달인자를 사용하지 않을 경우, “_”를 대신 사용한다.
func hello2(_ name: String, _ you: String) -> String {
return "\(name) say to \(you)"
}
hello2("swift", "python")
// "swift say to python"
내부의 전달인자 레이블을 다르게 사용하면 함수를 중복적(오버로드)으로 사용할 수 있다.
또한 매개변수에 기본값을 설정하여, 따로 함수에 값을 넘겨주지 않아도 실행가능하다.
func swift2python(_ name: String, _ you: String = "python") -> String {
return "\(name) say to \(you)"
}
swift2python("swift")
// "swift say to python"
또한 함수는 “가변 매개변수”라는 것을 가질 수 있다. 즉 매개변수에 몇 개의 값이 들어올지 모를 때 사용하는 것이며, 함수에서 가변 매개변수는 하나만 가질 수 있다.
func favoriteFood(n name: String, f foods: String...) -> String {
"\(name) likse \(foods)"
}
favoriteFood(n: "Cha", f: "chicken","pizza","beer")
// "Cha likse ["chicken", "pizza", "beer"]"
반환 값이 필요없는 함수도 있다. 이럴 때는 값이 없다를 말하는 “Void”를 명시해주거나, 아예 반환 타입 표현을 생략해줘도 된다.
func helloHi() -> Void {
print("Hi there")
}
helloHi()
// Hi there
위에서 봤을 때 보통, “(매개변수 타입의 나열) -> 반환 타입” 으로 작성을 하였으나 Void의 경우 아래처럼 작성할 수 있다.
- () -> Void
- (Void) -> Void
- () -> ()
맨 처음 함수가 일급객체라고 하면서, 함수를 전달인자로도, 반환 값으로 돌려 줄 수 있다고 했다.
아래 코드를 보자.
typealias TwoInts = (Int,Int) -> Int
func addTwo(_ a: Int, _ b: Int) -> Int {
return a + b
}
func minusTwo(_ a: Int, _ b: Int) -> Int {
return a - b
}
var calculate: TwoInts = addTwo
calculate(3,5)
// 8
calculate = minusTwo
calculate(5,3)
// 2
이렇게 함수를 타입으로도 사용 가능하며, 아래처럼 전달인자로 함수를 받을 수도 있다.
func calculateInts(_ math: TwoInts, _ a: Int, _ b: Int) {
"\(math(a,b))"
}
calculateInts(addTwo, 1, 2)
// 3
스위프트에는 종료되지 않는 함수가 있는데, 이는 비반환 함수로 반환 타입에 Never를 사용하여 표시해 주어 사용한다.
추가적으로 가끔은 반환값이 없는 함수를 사용할 때가 있는데, 이 때에는 함수의 반환값을 무시해도 된다는 키워드인 @discardableResult를 func 앞에 붙여서 사용한다.