함수는 코드를 재사용할 수 있게 한다.
이는 함수를 작성한 후에 그 함수를 다양한 곳에서 실행할 수 있다는 것을 의미한다.
코드를 반복하는 것은 일반적으로 좋지 않기에 함수는 이를 피할 수 있게 도와준다.
어플 사용자에게 도움 정보를 출력하는 함수를 작성한다. 어플의 어느 곳이든 이것이 필요하기 때문에 함수로 작성하는 것이 좋다.
Swift의 함수는 func 키워드로 시작하고 이후 함수 이름, 괄호가 있다. 함수의 바디(함수가 호출되었을 때 실행되는 코드)는 괄호 안에 위치한다.
func printHelp() {
let message = “””
Welcome to MyApp!
Run this app inside a directory of images and
MyApp will resize them all into thumbnails
“””
print(message)
}
printHelp()
실행할 때마다 함수를 커스터마이징할 수 있다면 함수는 매우 강력해진다.
Swift를 사용하면 함수에 값을 보낼 수 있고 이 값을 함수 내부에서 사용하여 동작 방식을 바꿀 수 있다.
우리는 이것을 이미 사용했다. – 우리는 print()함수에 문자열과 정수를 보냈었다.
print(“Hello, world!”)
파라미터를 받는 고유한 함수를 만들기 위해
각 파라미터에게 이름을 부여하고 이후에 콜론, 그 후에 파라미터의 타입을 적는다.
이 모든 것은 함수 이름 뒤의 괄호 안에 적혀진다.
func square(number:Int) {
print(number * number)
}
이것은 스위프트에게 number라고 불리는 정수형을 받을 것이라고 말해준다.
squre(number:8)
데이터를 받을 뿐만 아니라 함수는 데이터를 다시 보내기도 한다.
이것을 하기 위해, 함수의 매개변수(=파라미터) 목록 뒤에 대시(-)를 입력한 다음 꺾쇠 괄호(>)를 쓴 다음 어떤 종류의 데이터가 반환될 지 알려준다.
함수 안에서, return 키워드를 사용해서 값이 있는 경우 반환한다.
그러면 함수는 즉시 종료되고 그 값을 반환한다. – 함수의 어떤 코드도 실행되지 않는다.
func squre(number:Int) -> Int {
return number * number
}
let result = squre(number : 8)
print(result)
여러 값을 반환해야한다면, 튜플을 사용해야하는 경우 이것은 아주 좋은 예시이다.
func squre(number:Int) -> Int {
return number * number
}
매개변수 이름을 number 라고 지었기에 이것을 참조하기 위해 함수 안에서 number를 사용할 수도 있지만
let result = square(number: 8)
스위프트는 각 매개변수에 두 가지 이름을 제공할 수 있게 한다.
하나는 함수를 호출할 때 외부에서 사용되고
나머지 하나는 함수 내부에서 사용된다.
func sayHello(to name: String) {
print(“Hello, \(name)!”)
}
이 매개변수는 to name이라고 불린다.
이는 외부에선 to 라고 불리고 내부에선 name이라 불린다는 것을 의미한다.
sayHello(to: “Taylor”)
우리가 print()를 호출할 때는 사실 어떠한 매개변수도 전송하지 않는다 – 우리는 print(message: “Hello”)가 아니라 print(“Hello”)라고 한다.
func greet(_ person: String) {
print(“Hello, \(person)!”)
}
greet(“Taylor”)
언더바의 사용은 코드를 더 자연스럽게 읽을 수 있게 하지만
일반적으로 혼란을 피하기 위해 매개변수에게 대외 이름을 주는 것이 좋다.
print() 함수는 무언가를 스크린에 출력하지만
무엇을 출력하든지 마지막에 줄바꿈을 실행한다.
따라서 print()를 여러 번 호출하더라도 같은 줄에 나타나지 않는다.
원한다면 이 동작을 바꿀 수 있다.
예를 들어 줄 바꿈 대신 띄우기를 쓸 수 있다.
그러나 대부분 사람들은 새 줄을 원하기 때문에 print()는 새 줄을 디폴트 값으로 가지는 terminator 매개변수를 갖고 있다.
타입뒤에 = 를 적고 그 뒤에 제공하려는 디폴트 값을 작성하면
매개변수에 디폴트 값을 줄 수 있다.
func greet(_ person: String, nicely: Bool = true) {
if nicely == true {
print(“Hello, \(person)!”)
} else {
Print(“Oh no, it’s \(person) again…”)
}
}
greet(“Taylor”)
greet(“Taylor”, nicely: false)
일부 함수는 가변적이다.
이는 동일한 타입의 매개변수를 여러 개 받아들이는 방법이다.
print(“Haters”, “gonna”, “hate”)
너는 타입 뒤에 …을 적음으로써 어떤 매개변수도 가변적으로 만들 수 있다.
func squre(numbers: Int…) {
for number in numbers {
print(“\(number) squared is \(number * number)”)
}
}
square(numbers: 1,2,3,4,5)
입력이 잘못되었거나 내부적으로 문제가 발생하였을 때 함수는 실패하는 경우가 있다.
Swift는 반환 타입 전에 throw로 표시하여 무언가가 잘못되었을 때 throw 키워드를 사용하여 함수에서 오류를 throw 할 수 있게 한다.
우리는 패스워드가 맞는지 확인하는 함수를 작성하여 사용자가 확실한 패스워드를 작성했을 때 오류를 throw할 것이다.
enum PasswordError: Error {
case obvious
}
func checkPassword(_ password: String) throws -> Bool {
if password == “password” {
throw PasswordError.obvious
}
return true
}
Swift는 너의 프로그램이 실행될 때 오류가 발생하길 원하지 않는다.
이는 네가 오류를 발생하도록 가만 두지 않을 것이라는 의미이다 – 실수로 함수를 throwing하는 것
따라서 함수들을 세 키워드를 사용해서 호출해야한다.
만약 do 블럭 안에서 오류가 발생한다면 즉시 catch 블럭으로 넘어간다.
오류를 발생시키는 매개변수를 가진 checkPassword()를 호출해보자
do {
try checkPassword(“password”)
print(“That password is good!”)
} catch {
print(“You can’t use that password.”)
}
Swift의 함수에 전달된 모든 매개변수들은 상수이기 때문에 변경시킬 수 없다.
네가 원한다면, 하나 이상의 매개변수를 inout 으로 전달할 수 있다.
이것은 너의 함수 안에서 변경될 수 있고 그 변화가 함수 밖의 원래 값에 반영된다는 것을 의미한다.
func doubleInPlace(number : inout Int) {
number *= 2
}
var myNum = 10
doubleInPlace(number: &myNum)