함수를 사용하면 코드를 재사용할 수 있습니다. 따라서 코드를 반복적으로 작성하는 것을 방지할 수 있습니다.
또한 이렇게 작성한 함수는 여러 곳에서 함수를 호출(실행)할 수 있습니다.
스위프트 함수는 func
키워드를 붙인 후 함수 이름을 입력한 후 {}
괄호안의 실행할 코드를 작성합니다.
func printHelp() {
let message = "hello World"
print(message)
}
printHelp() // 함수호출(실행)
함수를 만들면 좋은 경우
함수에 값을 보낸 후 그 값을 가지고 함수 내부에서 사용할 수 있습니다.
함수에 보내는 값을 parameter
라고 합니다. 함수가 매개변수를 받아들이도록 하려면 각 매개변수에 이름을 지정한 다음 :
뒤에 타입을 정의합니다.
func square(number: Int) {
print(number * number)
}
square(number: 2)
❗️ 하나의 함수가 너무 많은 매개변수를 필요로 한다면 함수가 너무 많은 작업을 하고 있는지 생각해보고 나눠볼 필요가 있습니다.
함수는 값을 받을 뿐만 아니라 반환할 수도 있습니다.
반환하기 위해서는 ->
화살표를 사용한 후 반환할 타입을 정의하고 return
키워드에 값을 반환하면 됩니다.
반환되는 즉시 함수는 종료되고 다른 코드는 실행되지 않습니다.
반환하는 타입이 여러개인경우 튜플을 사용하는 것이 편리합니다.
func quize(answer: String) -> (result: String, money: Int) {
if answer == "sookim" {
return ("ok", 100)
}
return ("no", 0)
}
print(quize(answer: "sookim")) // (ok, 100)
코드블럭 안에 return이 오직 한번만 사용될 때 생략 가능합니다. (Swift 5.1)
함수나 클로저, computed-property, 삼항연산자에서 생략 가능합니다.
struct Student {
func whatToDo() -> String {
"Just Play!" // 매소드에서 return 키워드가 없이 값 반환 가능
}
}
매개변수 이름을 지정하면 함수 바깥, 내부에서 모두 같은 이름을 사용해야 합니다. 스위프트에서는 매개변수에 두가지 이름을 제공할 수 있습니다.
공백으로 함수 외부, 내부에서의 사용할 이름을 구분합니다.
func sayHello(to name: String) {
print("Hello, \(name)!") // 함수내부에서는 name을 사용합니다.
}
sayHello(to: "Taylor") // 함수외부에서는 to를 사용합니다.
함수를 호출할 때 매개변수 이름생략을 할 수 있습니다. 생략하는 방법은 호출할 때 사용할 매개변수이름을 _
로 지정합니다.
func greet(_ person: String) {
print("Hello, \(person)!")
}
greet("Taylor")
생략을 하면 코드를 자연스럽게 읽을 수 있지만 매개변수이름이 있는 경우 의미하는 바를 이해하기 쉬운 경우도 있기 때문에 상황에 따라 판단하는 것이 좋을 수 있습니다.
스위프트에서는 매개변수에 기본값을 설정할 수 있습니다.
기본값을 설정하려면 =
뒤에 원하는 값을 설정합니다.
기본값을 설정한 매개변수는 함수를 호출할 때 생략이 가능합니다.
func greet(_ person: String, to nicely: Bool = true) {
if nicely == true {
print("Hello, \(person)!")
} else {
print("Oh no, it's \(person) again...")
}
}
greet("Taylor")
greet("Taylor", to: false)
스위프트의 함수는 가변인자(가변매개변수)를 받을 수 있습니다.
가변인자는 임의의 갯수의 인수를 받을 수 있다는 뜻입니다. 사용방법은 매개변수 타입 이름 뒤에 ...
을 붙여줍니다.
함수를 호출할 때는 매개변수를 ,
쉼표로 구분하여 전달합니다.
전달받은 가변매개변수는 함수내에서 배열로 반환됩니다.
func square(numbers: Int...) {
for number in numbers {
print("\(number) squared is \(number * number)")
}
}
square(numbers: 1, 2, 3, 4, 5)
// 실행결과
1 squared is 1
2 squared is 4
3 squared is 9
4 squared is 16
5 squared is 25
함수에서 입력이 잘못되었거나 내부적으로 문제가 발생하여 실패하는 경우가 있습니다. 이런 경우 throws
키워드를 사용하여 문제가 발생할 때 오류를 발생시킬 수 있습니다.
첫번째로 오류를 설명하는 enum
타입을 정의한후 스위프트의 기존 Error
프로토콜을 채택합니다. 그 후 함수매개변수괄호 뒤에 throws
키워드를 추가합니다.
함수가 동작하면서 오류가 발생한 부분에 throw
키워드를 추가해 오류값을 반환해줍니다.
enum PasswordError: Error {
case obvious
}
func checkPassword(_ password: String) throws -> Bool {
if password == "password" {
throw PasswordError.obvious
}
return true
}
언제 throwing functions을 작성해야 할까?
스위프트에서 throwing함수는 처리 할수없는 오류가 발생할 수 있는 기능입니다. throwing함수를 사용하면 모든 오류가 처리되도록 해야하기 때문에 여러 위치에서 오류처리를 할 필요가 있을 수 있습니다.
https://www.donnywals.com/working-with-throwing-functions-in-swift/
스위프트는 오류 발생하는 것을 좋아하지 않습니다.
throwing functions를 호출할 때는 do ~ try catch
를 사용하여 호출합니다.
do
: 문제를 일으킬 수 있는 코드 범위try
: 오류를 발생시킬수 있는 코드 , 모든 함수보다 먼저 실행catch
: 오류를 처리하는 코드 범위do 블록내부에서 오류가 발생하면 즉시 catch블록으로 이동합니다.
do {
print("start")
try checkPassword("password")
print("That password is good!")
} catch {
print("You can't use that password.")
}
// 실행결과
start
You can't use that password.
스위프트함수에 전달되는 모든 매개변수는 상수이므로 변경할 수 가 없습니다. 원하는 경우 inout
키워드를 사용하여 함수내에서 변경할 수 있으며 이렇게 변경된 값을 반환할 수 있습니다.
inout
뒤 매개변수는 변수여야 합니다.
주소를 참조하기 때문에 함수내부에서 변경되어도 매개변수로 넣어준 값이 같이 변경됩니다.
func doubleInPlace(number: inout Int) {
number *= 2
}
var myNum = 10
doubleInPlace(number: &myNum)
print(myNum)
// 실행결과
20