티스토리 뷰
이번 포스트에서는 Swift에서의 함수에 대해 알아보도록 하겠습니다.
Swift에서 함수를 생성하는 방법은 다음과 같습니다.
func 함수명(인자 이름: 타입) -> 리턴 타입 {
(함수 본체)
return (반환 값)
}
정의한 함수를 호출하는 방법은 다음과 같습니다.
func plus(num1: Int, num2: Int) -> Int {
return num1 + num2
}
print(plus(1, 2)) // 3
함수의 Parameter Value와 Return Value
Parameter가 없는 함수
func sayHelloWorld() -> String {
return "hello, world"
}
print(sayHelloWorld())
// Prints "hello, world"
복수의 Parameter가 있는 함수
func greet(person: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return greetAgain(person: person)
} else {
return greet(person: person)
}
}
print(greet(person: "Tim", alreadyGreeted: true))
// Prints "Hello again, Tim!"
Return Value가 없는 함수
func greet(person: String) {
print("Hello, \(person)!")
}
greet(person: "Dave")
// Prints "Hello, Dave!"
NOTE
위 함수는 반환 값을 선언하지는 않았지만 반환 값은 존재합니다. 반환 값이 정의 되지 않은 함수는 Void라는 특별한 타입을 반환합니다. Void는 간단히 ()를 사용한 빈 값(타입)입니다.
복수의 값을 Return 하는 함수
func minMax(array: [Int]) -> (min: Int, max: Int) {
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
위 코드는 정수형 리스트를 파라미터로 받아서 최대 값과 최소 값을 튜플 형식으로 반환해주는 함수입니다.
옵셔널 튜플 반환 형
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty { return nil }
var currentMin = array[0]
var currentMax = array[0]
for value in array[1..<array.count] {
if value < currentMin {
currentMin = value
} else if value > currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
위 코드를 살펴보면 반환 값에 ? 가 붙었습니다. 실제 반환 값에 접근하기 위해서는 if let과 같은 옵셔널 체인(Optional Chaining)을 사용하거나 강제 unwrapping을 해야 합니다.
함수 인자 레이블과 파라미터 이름
함수 호출시 적절한 파라미터 이름을 지정해 함수 내부와 함수 호출시 사용할 수 있습니다.
func someFunction(firstParameterName: Int, secondParameterName: Int) {
// 함수 내부에서 firstParameterName와 secondParameterName의 인자를 사용합니다.
}
someFunction(firstParameterName: 1, secondParameterName: 2)
파라미터 레이블 지정 ( Specifying Arguments Label )
파라미터 앞에 인자 레이블을 지정해 실제 함수 내부에서 해당 인자를 식별하기 위한 이름과 함수 호출시 사용하는 이름을 다르게 해서 사용할 수 있습니다.
func someFunction(argumentLabel parameterName: Int) {
// 함수 안애서 parameterName로 argumentLabel의 인자값을 참조할 수 있습니다.
}
아래 소스 코드는 Arguments Labels을 지정해서 함수 내부에서는 hometown으로 값을 제어하고 함수 호출시에는 인자 값으로 from을 사용한 예시 코드입니다.
func greet(person: String, from hometown: String) -> String {
return "Hello \(person)! Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
// Prints "Hello Bill! Glad you could visit from Cupertino."
인자 생략 (Omitting Argument Labels)
파라미터 앞에 _를 붙여 함수 호출시 인자값을 생략할 수 있습니다.
func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
// 함수 안에서 firstParameterName, secondParameterName
// 인자로 입력받은 첫번째, 두번째 값을 참조합니다.
}
someFunction(1, secondParameterName: 2)
기본 파라미터 값
함수의 파라미터 값에 기본 값(ex. test: Int = 12)을 설정할 수 있습니다. 기본 값이 설정 되어 있는 파라미터는 함수 호출시 생략할 수 있습니다. 기본 값을 사용하지 않는 파라미터를 앞에 위치 시켜야 함수를 의미있게 사용하기 쉽습니다.
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
// 함수 호출시 두번째 인자를 생략하면 함수안에서
// parameterWithDefault값은 12가 기본 값으로 사용됩니다.
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) // parameterWithDefault는 6
someFunction(parameterWithoutDefault: 4) // parameterWithDefault는 12
집합 파라미터
인자 값으로 특정 형(type)의 집합 값을 사용할 수 있습니다.
func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers
인-아웃(Inout) 파라미터
인자 값을 직접 변경하는 파라미터 입니다. 선언을 위해 파라미터 앞에 inout 이라는 키워드를 사용합니다. 아래는 인자 두 값을 변경하는 함수입니다.
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
아래는 실제로 사용하는 예시 코드입니다. 함수의 인자에 변수를 넣을때 & 키워드를 넣었습니다. C언어를 해본 적이 있다면 inout파라미터는 포인터를 넣는다고 생각하면 좋을 것 같습니다.
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// Prints "someInt is now 107, and anotherInt is now 3"
두 변수의 실제 값이 바뀐 것을 확인하실 수 있습니다.
NOTE
인-아웃 파라미터는 기본 값을 갖을 수 없고, 집합 파라미터는 inout으로 선언될 수 없습니다. 인-아웃 파라미터를 사용하는 것은 함수의 반환 값을 사용하지 않고 함수 scope 밖에 영향을 줄 수 있는 또 하나의 방법입니다.
함수 형 (Function Types)
함수의 형은 파라미터 형과(parameter types) 반환 형(return type)으로 구성 돼 있습니다. 아래 두 함수는 Int값 두 개를 입력받고 Int를 반환하는 함수입니다.
func addTwoInts(_ a: Int, _ b: Int) -> Int {
return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
return a * b
}
아래는 입력 받는 파라미터와 반환 값이 없는 함수입니다.
func printHelloWorld() {
print("hello, world")
}
함수 형 (Function Type)의 사용
아래와 같이 함수를 변수처럼 정의해서 사용할 수 있습니다.
var mathFunction: (Int, Int) -> Int = addTwoInts
변수 mathFunction는 addTwoInts 함수의 인자 값과 반환 값이 같으므로 이 함수가 변수로 할당 될 수 있습니다. 아래는 이렇게 변수에 함수를 할당해 사용한 예시 코드입니다.
print("Result: \(mathFunction(2, 3))")
// Prints "Result: 5"
multiplyTwoInts 함수도 mathFunction과 함수 형이 같으므로 할당해 사용할 수 있습니다
mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2, 3))")
// Prints "Result: 6"
Swift가 데이터의 타입을 자동으로 추론해(Type Inferred) 자동으로 함수를 할당할 수 있습니다.
(구체적으로 직접 타입을 지정할 필요가 없습니다.)
let anotherMathFunction = addTwoInts
// anotherMathFunction is inferred to be of type (Int, Int) -> Int
파라미터 타입으로 제공하는 함수 형 (Function Types as Parameter Types)
func printMathResult(_ mathFunction: (Int, Int) -> Int, _ a: Int, _ b: Int) {
print("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5)
// Prints "Result: 8"
Swift에서는 함수의 파라미터로 함수 형을 넣어줄 수 있습니다.
반환형으로 제공하는 함수 형 (Function Types as Return Types)
Swift에서는 함수 형을 반환할 수도 있습니다.
func stepForward(_ input: Int) -> Int {
return input + 1
}
func stepBackward(_ input: Int) -> Int {
return input - 1
}
입력한 step에 하나를 더하거나 빼는 함수를 선언했습니다. 이 함수를 리턴값으로 사용할 수 있습니다. 아래 코드는 backward함수가 true냐 false냐에 따라 위에서 선언한 적절한 함수를 반환하는 함수입니다.
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
return backward ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero는 이제 stepBackward() 함수를 가르키고 있습니다.
moveNearerToZero를 호출할 때마다 stepBackward() 함수가 호출돼 입력 값이 1씩 줄어들어 결국 0이 됩니다.
print("Counting to zero:")
// Counting to zero:
while currentValue != 0 {
print("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!
중첩 함수 (Nested Functions)
지금까지 함수는 전역적으로 동작하도록 선언했습니다.
함수 중에는 다른 함수 안의 body에서 동작하는 함수가 있는데 이 함수를 중첩 함수(Nested Function) 이라 합니다.
중첩함수는 함수 밖에서는 감춰져 있고 함수의 body내에서 접근 가능합니다.
위의 chooseStepFunction을 중첩 함수를 이용해 아래처럼 다시 작성할 수 있습니다.
func chooseStepFunction(backward: Bool) -> (Int) -> Int {
func stepForward(input: Int) -> Int { return input + 1 }
func stepBackward(input: Int) -> Int { return input - 1 }
return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero는 이제 중첩 돼 있는 stepForward() 함수를 가르킵니다.
while currentValue != 0 {
print("\(currentValue)... ")
currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!
이번 포스트에서는 Swift의 함수에 대해 살펴봅았습니다.
'프로그래밍언어 > Swift' 카테고리의 다른 글
[Swift] Delegate 패턴 사용하기 (0) | 2020.03.13 |
---|---|
Swift 클로저 (Closure) (0) | 2020.02.23 |
Swift 메모리 안정성 (0) | 2020.02.16 |
Swift 제어문 (조건문, 반복문) (0) | 2020.02.14 |
Swift Collection Types (컬렉션 타입) (0) | 2020.02.10 |
- Total
- Today
- Yesterday
- Auto Layout
- watchos
- databinding
- apple
- Apple Watch
- 코틀린
- 컬렉션
- Swift
- SwiftUI
- 스위프트
- Kotlin
- Notissu
- 알고리즘
- C++
- 상속
- CloudComputing
- retrofit
- 애플워치
- ios
- java
- 아이폰
- Elliotable
- 안드로이드
- 오토레이아웃
- 함수형프로그래밍
- Rxjava
- XCode
- Reactive programming
- android
- 함수형
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |