함수란 무엇이냐 바로 function이다.
이게 뭔소리냐...
넘어가고 진짜 함수는 바로 인풋이 있다면 아웃풋이 있는 것이다.
Swift에서 함수은 다음과 같이 선언한다.
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 ...) -> 반환타입 {
/* 함수 구현부 */
return 반환값
}
// 예)
// sum이라는 이름을 가지고
// a와 b라는 Int 타입의 매개변수를 가지며
// Int 타입의 값을 반환하는 함수
func sum(a: Int, b: Int) -> Int {
return a + b
}
매개변수라는 것이 들어가게 되면 그것에 대한 작동이 이루어지고 return을 통해 아웃풋이 도출되는 형태. 바로 이것이 함수이다.
반환 값이 없는 함수도 있다.
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 ...) -> Void {
/* 함수 구현부 */
return
}
// 예)
func printMyName(name: String) -> Void {
print(name)
}
// 반환 값이 없는 경우, 반환 타입(Void)을 생략해 줄 수 있습니다
func printYourName(name: String) {
print(name)
}
아니 반환값이 없는 것도 있네요? 그럼 매개변수가 없는 것도 있어요?
네 있습니다.
매개변수가 없는 경우엔
func 함수이름() -> 반환타입 {
/* 함수 구현부 */
return 반환값
}
// 예)
func maximumIntegerValue() -> Int {
return Int.max
}
이런 식인거죠 함수이름() 이 괄호안에 아무것도 없는거에요.
아니 그러면, 그러면요 반환값도 없고 매개변수도 없고 그냥 자기 할 일만 하는 경우가 있을 수도 있잖아요!
네 맞습니다. 둘 다 없는 경우도 존재해요!
func 함수이름() -> Void {
/* 함수 구현부 */
return
}
// 함수 구현이 짧은 경우
// 가독성을 해치지 않는 범위에서
// 줄바꿈을 하지 않고 한 줄에 표현해도 무관합니다
func hello() -> Void { print("hello") }
// 반환 값이 없는 경우, 반환 타입(Void)을 생략해 줄 수 있습니다
func 함수이름() {
/* 함수 구현부 */
return
}
func bye() { print("bye") }
모든 걸 생략해서 단 한 줄에 코드가 끝날 수 있는거에요.
그러면 우리가 이렇게 만든 함수를 불러낼려면 어떻게 해요?
그건 간단합니다.
sum(a: 3, b: 5) // 8
printMyName(name: "ted") // ted
printYourName(name: "hana") // hana
maximumIntegerValue() // Int의 최댓값
hello() // hello
bye() // bye
그냥 함수이름() 하면됩니다. 물론 매개변수가 있는 경우엔 다르겠지만!?
아니 근데요 무조건 파라미터 이름을 정해진 대로 해야해요??
-> 아닙니다.
다음과 같은 경우엔 우리가 원하는 대로 파라미터 이름을 받는 모습을 볼 수 있어요.
func hello(to name: String, numberOfTimes time: Int) {
// 함수 내부에서는 name, time을 사용
for _ in 0..<time {
print(name)
}
}
hello(to: "Mark", numberOfTimes: 3) // 함수 호출 시에는 to, numberOfTimes
만약 그러면 제가 넣고자하는 매개변수가 갯수를 모르겠어요... 이럴 때에는 어떻게 해요?
바로 그럴땐 ...
을 사용하면 됩니다.
이렇게 말이죠~
func sum(_ numbers: Int...) -> {
//...
}
근데 함수안에 또 다른 함수를 넣어서 같이 실행되게 할 수 있어요?
네 그럼요 가능합니다.
func hello(name: String, time: Int) {
func message(name: String) {
return "\(name)님 안녕하세요!"
}
for _ in 0..<time {
print(message(name: name))
}
}
다음과 같이 한다면 상위 함수에서 받은 매개변수를 하위 함수에서도 사용할 수 있겠죠??
아니 그러면 여태 매개변수 값만 반환하신거 같은데 함수를 반환할 수도 있어요?
네 그럼요~
func helloGenerator(message: String) -> (String) -> String {
func hello(name: String) -> String {
return name + message
}
return hello
}
let hello = helloGenerator(message: "님 안녕하세요!")
hello("Ted") // Ted님 안녕하세요!
이 부분을 보면 아시겠지만 함수 자체를 반환하게되면 밖에서 hello()를 통해서 접근이 가능한 것을 볼 수 있어요!
어 근데요 만약에 변수를 넣을 때 기본적으로 사용되는 기본값을 지정해주고 싶다면 어떻게 해야해요?
바로 이렇게 하면 됩니다.
func 함수이름(매개변수1이름: 매개변수1타입, 매개변수2이름: 매개변수2타입 = 매개변수 기본값 ...) -> 반환타입 {
/* 함수 구현부 */
return 반환값
}
func greeting(friend: String, me: String = "Ted") {
print("Hello \(friend)! I'm \(me)")
}
// 매개변수 기본값을 가지는 매개변수는 호출시 생략할 수 있습니다
greeting(friend: "hana") // Hello hana! I'm Ted
greeting(friend: "john", me: "eric") // Hello john! I'm eric
오오 그럼 만약 함수를 변수나 상수에 할당하는 것도 가능해요?
네 가능합니다.
대신 서로 타입이 다른 함수라면 할당이 되지 않아요!
var someFunction: (String, String) -> Void = greeting(to:from:)
someFunction("eric", "Ted") // Hello eric! I'm Ted
someFunction = greeting(friend:me:)
someFunction("eric", "Ted") // Hello eric! I'm Ted
// 타입이 다른 함수는 할당할 수 없습니다 - 컴파일 오류 발생
//someFunction = sayHelloToFriends(me: friends:)
func runAnother(function: (String, String) -> Void) {
function("jenny", "mike")
}
// Hello jenny! I'm mike
runAnother(function: greeting(friend:me:))
// Hello jenny! I'm mike
runAnother(function: someFunction)
지금까지 Swift의 함수에 대해서 알아보았다! 다음은 함수의 또 다른 함수 옵셔널에 대해서 해보겠다.