Defining and Calling Functions
: Swift 에서는 Function도 타입을 가질 수 있다. 타입을 구별하는 요소는 Function의 parameter type과 return type이다.
func greet(person: String) -> String {
let greeting = "Hello, " + person + "!"
return greeting
}
print(greet(person: "Anna"))
// Prints "Hello, Anna!"
print(greet(person: "Brian"))
// Prints "Hello, Brian!"
Function Parameters and Return Values
: Swift Function의 parameter와 return value의 형태는 매우 다양하다. 이제 하나하나씩 알아볼 것이다.
Functions Without Parameters
return 값만 있고 parameter는 존재하지 않는 함수다.
func sayHellosWorld() -> String {
reutrn "hello, world"
}
print(sayHelloWorld())
Functions With Multiple Parameters
여러개의 parameter와 return 값이 있는 function 이다.
func greet(person: String, alreadyGreeted: Bool) -> String {
if alresyGreeted {
return greetAgain(person: person)
} else {
return greet(person: person)
}
}
print(greet(person: "Tim", alreadyGreeted: true))
이 함수는 우리가 위에서 정의한 greet(person:) 함수와 이름이 똑같다. 하지만 parameter의 타입이 다르기 때문에 서로 다른 타입으로 구별된다.
Functions Without Return Values
return Value를 갖지 않는 Function 이다.
func greet(person: String) {
print("Hello, \(person)!")
}
greet(person: "Dave")
엄밀히 말하면, 위 함수는 값을 전혀 return하지 않는것이 아니고, Void type을 return한다. 이것은 empty tuple '()'로 표현될 수 있다.
Functions with Multiple Return Values
: return type으로 tuple을 지정할 수 있다.
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)
}
let bounds = minMax(array: [8, -6, 2, 109, 3, 71])
print("min is \(bounds.min) and max is \(bounds.max)")
// Prints "min is -6 and max is 109"
Optional Tuple Return Types
: return type이 tuple인데 nil이 될 가능성이 있는경우 뒤에 '?'을 붙여서 optional type으로 만들어야 한다.
단, (Int, Int)? 와 (Int?, Int?)는 구분해야 한다. 전자는 튜플 자체가 optional type이고 후자는 튜플안에 있는 각각의 타입이 optional type인 것이다.
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 bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
print("min is \(bounds.min) and max is \(bounds.max)")
}
// Prints "mins is -6 and max is 109"
Function Argument Labels and Parameter Names
: Function의 구성요소로 Argument Label과 Parameter Name이 있다.
Argument Label은 function을 call 할때 각각의 argument 앞에 붙여서 사용하고 parameter name은 함수 내부에서 넘어온 argument를 사용할 때 사용한다.
기본적으로 argument Label을 따로 지정해 주지 않으면 parameter name을 argument Label로 사용한다.
func someFunction(firstParameterName: Int, secondParameterName: Int)
{
// 따로 argument Label을 지정해주지 않았으므로
// firstParameterName, secondParameterName은 parameter name이 됨과 동시에 argument Label이 된다.
}
specifying Argument Labels
: Argument Label을 지정하는 경우를 살펴보자.
func someFunction(argumentLabel parameterName: Int)
{
// argument label이 지정된 경우이다. 함수 내부에서는 parameter name을 써야하고
// 함수를 호출할 때에는 argument label을 사용해야 한다.
}
여러개의 parameter가 존재할 경우 argumentLabel을 일부 생략할 수도 있다.
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
: argument label을 사용하고 싶지 않다면 '_'을 추가해서 생략할 수 있다.
func someFunction(_ firstParameterName: Int, secondParameterName: Int)
{
// body...
}
someFunction(1, secondParameterName: 2)
Default Parameter Values
: parameter에 Default value를 지정하는 방법을 알아보도록 하자.
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12)
{
// body...
}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6)
someFunction(parameterWithoutDefault: 4) // 이 경우 두번째 parameter에 12가 자동 지정되어 함수가 호출된다.
Variadic Parameters
: 가변 갯수 파라미터를 뜻한다.
가변 갯수 파라미터로 넘어오면 constant array로 취급된다.
함수는 최대 하나의 variadic parameter를 가질 수 있다.
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)
arithmeticMean(3, 8.25, 18.75)
In-Out Parameters
: 전산 전공자라면, 학부때 call-by-value, call-by-reference 개념을 배웠을 것이다.
swift는 함수의 parameter가 default로 상수(let)로 취급되고, 기본 타입(Int, Double . . . )이 구조체이기 때문에 call-by-value로 동작한다.
swift는 이러한 제약을 탈피하고자 In-Out Parameter라는 문법을 제공한다.
func swapTwoInts(_ a: inout Int, _b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
in-out parameter로 상수, literal 값을 넘길 수 없다. 오직 변수(var)만 가능하다.
또한, in-out parameter는 default 값을 가질 수 없고 variadic parameter는 in-out parameter가 될 수 없다. in-out parameter로 변수를 넘길 때 앞에 '&'을 붙여서 값이 변경될 것이라는 것을 표시한다.
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"
Function Types
: 모든 function은 type을 가지고 있고, type은 parameter type과 return type에 의해 구별된다.
func addTwoInts(_ a: Int, _b: Int) -> Int
{
return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int
{
return a * b
}
두 함수의 타입은 (Int, Int) -> Int로 서로 같다.
Using Function Types
: function type은 다른 type들과 다를 것이 없다. 예를들어, function type의 변수, 상수를 만드는 것이 가능하다.
var mathFunction: (Int, Int) -> Int = addTwoInts
print("Result: \(mathFunction(2, 3))")
// Prints "Result : 5"
mathFunction = multiplyTwoInts
print("Result: \(mathFunction(2, 3))")
// Prints "Result: 6"
// multiplyTwoInts는 addTwoInts와 같은 타입이니 같은 변수에 대입할 수 있다.
let anotherMathFunction = addTwoInts
// anotherMathFunction은 (Int, Int) -> Int 으로 타입추론 된다.
Function Types as Parameter Types
: function type을 parameter type으로 사용하여 function도 parameter로 넘길 수 있다.
func printMathResult(_ mathFunction: (Int, Int) -> Int, _a: Int, _ b:Int)
{
print("Result: \(mathFunction(a, b))")
}
printMathResult(addTowInts, 3, 5)
// Prints "Result: 8"
Function Types as Return Types
: function을 함수의 return type으로 사용할 수 있다.
func stepForward(_ input: Int) -> Int
{
return input + 1
}
func stepBackward(_ input: Int) -> Int
{
return - 1
}
func chooseStepFunction(backward: Bool) -> (Int) -> Int
{
return backward ? stepBackward : stepForward
}
var currentValue = 3
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero 는 stepBackward()를 가리키게 된다.
print("Counting to zero:")
while currentValue != 0
{
print("\(currentValue)...")
currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// 3...
// 2...
// 1...
// zero!
Nested Functions
: Nested Function은 function안에 존재하는 function이다.
위 chooseStepFunction(backward:) 예제를 Nested Function을 통해 구현할 수 있다.
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!
'IOS > Swift' 카테고리의 다른 글
[Swift 4.0] Enumerations (0) | 2017.04.01 |
---|---|
[Swift 4.0] Closures (0) | 2017.04.01 |
[Swift 4.0] Control Flow (0) | 2017.04.01 |
[Swift 4.0] Collection Types (0) | 2017.02.03 |
[Swift 4.0] Strings and Characters (0) | 2017.01.22 |