티스토리 뷰

iOS

[Swift] 함수 (Functions) (1)

Peppo 2022. 1. 19. 21:53
728x90

함수 (Functions)

 

함수란 특정 작업을 수행하는데 포함된 코드 덩어리 입니다.

Swift의 모든 함수는 parameter(매개변수)와 return(반환)으로 구성되어 있습니다.

파라미터로 함수를 가질수도, 반환값에 함수가 있을수도, 함수안에 함수가 있게도 할 수 있습니다.

 

들어가기전에 명칭을 눈에 익혀두고 가시죠!!

 


정의와 호출 (Defining nad Calling Functions)

 

먼저 함수의 형태를 예제로 보겠습니다.

 

함수를 선언할 때는

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}

'func' 키워드로 함수라는걸 알리고 

- func 뒤에는 함수명

- 함수명 뒤에는 (파라미터: 타입) , 파라미터가 없으면 ( ) 

- 파라미터 뒤에는 -> 반환타입

 

 

함수를 호출할 때는 

greet(person: "Peppo")

- 함수명(인자값) 

 

 


함수 파라미터와 반환 값 (Function Parameters and Return Values)

Swift에서의 함수 파라미터와 반환 값은 유동적으로, 

이름없는 단일 파라미터의 함수부터 복잡한 파라미터의 함수까지 다양하게 선언할수 있습니다.

 

파라미터가 없는 함수 (Functions Without Parameters)

func sayHelloWorld() -> String {
    return "hello, world"
}
print(sayHelloWorld())

파라미터가 없더라도 함수 이름뒤엔 괄호() 가 있어야하며, 

함수가 호출될 때도 빈괄호()가 필요합니다.

 

 

복수의 파라미터를 사용하는 함수 (Functions With Multiple Parameters)

func greet(person: String) -> String {
    let greeting = "Hello, " + person + "!"
    return greeting
}

func greetAgain(person: String) -> String {
    return "Hello again, " + person + "!"
}

// 복수의 파라미터 사용
func greeting(person: String, alreadyGreeted: Bool) -> String {
    if alreadyGreeted {
        return greetAgain(person: person)
    } else {
        return greet(person: person)
    }
}

print(greeting(person: "Tim", alreadyGreeted: true))
// Hello again, Tim!

greeting의 함수 호출 부분 (제일하단) 에서 alreadyGreeted의 값이 true 이므로 

greetAgain 함수가 호출되어 "Hello again, Tim!" 이 출력됩니다.

 

 

반환 값이 없는 함수 (Functions Without Return Values)

func greet(person: String) {
    print("Hello, \(person)!")
}
greet(person: "Dave")
// Prints "Hello, Dave!"
NOTE

위 함수는 반환 값을 선언 하진 않았지만 반환 값이 있습니다.
반환 값이 정의 되지 않은 함수는 Void 타입의 특별 값을 반환 합니다.

 

 

반환 값은 아래와 같이 호출 될때 무시될 수 있습니다.

func printAndCount(string: String) -> Int {
    print(string)
    return string.count
}
func printWithoutCounting(string: String) {
    let _ = printAndCount(string: string)
}
printAndCount(string: "hello, world")
// prints "hello, world" and returns a value of 12
printWithoutCounting(string: "hello, world")
// prints "hello, world" but does not return a value

첫번째 함수는 문자열을 print 하고, 문자갯수(string.count)를 Int로 반환 합니다.

두번째 함수는 첫번째 함수를 호출 하지만 반환 값은 무시합니다. 

 

복수의 값을 반환하는 함수(Functions with Multiple Return Values)

튜플을 함수의 반환 값으로 사용할 수 있습니다.

아래는 최소값, 최대값을 구하는 예제입니다.

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)
}

minMax 함수에서 반환값이 (min:, max:) 두개 이므로 해당 함수를 호출하면 두개가 반환되기도 하지만,

점(.) 으로 접근해 값을 하나만 가져올 수 도 있습니다.

let bounds = minMax(array: [8, -6, -2, 109, 3, 71])

print("bounds:", bounds)         // (min: -6, max: 109)
print("bounds.min:",bounds.min)  // -6
print("bounds.max:",bounds.max)  // 109

 

옵셔널 튜플 반환형 (Optional Tuple Return Types)

만약 반환 값이 없을 경우에는 반환 값을 나타내주는곳에  물음표(옵셔널)를 사용하여 nil일 경우를 대비할 수 있습니다.

이렇게요. (min: Int, max: Int)?

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)
}

 

옵셔널 바인딩을 사용하여 함수가 nil을 반환하는지 확인할 수 있습니다.

if let bounds = minMax(array: [8, -6, 2, 109, 3, 71]) {
    print("min is \(bounds.min) and max is \(bounds.max)")
}
// min is -6 and max is 109

 

 

암시적 반환이 있는 함수 (Functions With an Implicit Return)

 

하나의 리턴 라인으로 작성하는 모든 함수는 리턴을 생략할 수 있습니다.

func greeting(for person: String) -> String {
    "Hello, " + person + "!"
}
print(greeting(for: "Dave"))
// Prints "Hello, Dave!"

func anotherGreeting(for person: String) -> String {
    return "Hello, " + person + "!"
}
print(anotherGreeting(for: "Dave"))
// Prints "Hello, Dave!"

 

 

함수 인자 레이블과 파라미터 이름 (Function Argument Labels and Parameter Names)

 

함수 호출시 적절한 파라미터 이름을 지정해 함수 내부에서 또는 함수 호출시 사용할 수 있습니다.

func someFunction(firstParamName: Int, secondParamName: Int) {
    // 함수 내부에서 firstParamName secondParamName 인자를 사용
}
someFunction(firstParamName: 1, secondParamName: 2)

 

 

인자 레이블 지정 (Specifying Argument Labels)

파라미터 앞에 인자 레이블을 지정해 실제 함수 내부에서 해당 인자를 식별하기 위한 이름과

함수 호출시 사용하는 이름을 다르게 해서 사용할 수 있습니다.

func someFunction(argumentLabel paramName: Int) {
    // 함수 내부에서 paramName으로 argumentLabel의 인자값을 참조할 수 있습니다.
}

 

아래는 인자 레이블을 from 으로 지정하고 함수 내부에서는 hometown 으로 값을 제어하는 예 입니다.

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)

 

 

기본 파라미터 값 (Default Parameter Values)

아래의 형태로 함수 파라미터의 기본 값을 설정할 수 있습니다. 

(파라미터이름: Int = 12) 

기본 값이 설정된 파라미터는 함수 호출시 생략할 수 있으므로,

기본 값을 사용하지 않는 파라미터를 앞에  위치 시켜 가독성을 높여줄 수 있습니다.

func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {
    // 함수 호출시 두번째 인자를 생략하면
    // parameterWithDefault값은 12가 기본 값으로 사용됩니다.
}

// 두번째 인자에 값을 부여하면 값이 변경됩니다.
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6)
// parameterWithDefault는 6
someFunction(parameterWithoutDefault: 4)
// parameterWithDefault는 12

 

 

가변 파라미터 (Variadic Parameters)

가변 파라미터는 특정 타입의 0이상의 값을 받아들이며, 

형태는 타입뒤에 마침표 세개 (...)를 붙여 작성합니다.

 

인자로 넘긴 값들은 파라미터에서 지정한 타입의 배열로 만들어 집니다. 

아래는 평균을 구하는 함수 예제 입니다.

func arithmeticMean(_ numbers: Double...) -> Double {
    var total: Double = 0
    print("numbers의 갯수는: ",numbers.count)
    for number in numbers {
        total += number
    }
    return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// print numbers의 갯수는: 5
// return 3.0 (평균 값)

 

 

입출력 파라미터 (In-Out Parameters)

파라미터 값이 변경된 이후에도 값이 유지되길 원한다면, 입출력 파라미터로 정의해야 합니다.

 

형태는 파라미터의 타입 앞에 inout 키워드를 적어줍니다.

(파라미터이름: inout Int

 

입출력 파라미터는 함수로 넘겨진 값을 가지며, 함수에 의해 수정된 값을 밖으로 넘깁니다.

값이 바뀌기 때문에 입출력 파라미터엔 변수만 넘길수 있으며, 

변수에 넘길때 앤드 기호 (&)를 변수 앞에 붙여 값이 함수에 의해 변경 될 수 있음을 알려줍니다.

 

NOTE

입출력 파라미터는 기본 값을 가질수 없으며, 가변 파라미터에 inout 키워드를 붙일 수 없습니다.

 

아래 입출력 파라미터 예제를 보시죠.

var someInt = 3
var anotherInt = 107

print("Before someInt: \(someInt), anotherInt: \(anotherInt)")
//  Before someInt: 3, anotherInt: 107

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

swapTwoInts(&someInt, &anotherInt)

print("After someInt: \(someInt), anotherInt: \(anotherInt)")
//  After someInt: 107, anotherInt: 3

 

변형되는 순서는 아래와 같습니다.

  1. (&someInt, &anotherInt)의 인자를 갖고 swapTwoInts 함수를 실행
  2. & 키워드가 있으므로 인자로 들어온 변수들 값이 변경될 걸 알 수 있음.
  3. swapTwoInts함수에서 a와b의 값이 변경됨 (로직 참고)
  4. 변경된 값을 someInt, anotherInt의 값으로 넘김

 

입출력 파라미터 이해하는데 한참 걸렸네요... 

나머지 함수형 (Function Types) 은 다음 블로깅에 정리!!

함수 (Functions) (2) 정리했습니다.

728x90

'iOS' 카테고리의 다른 글

ModernRIBs_tutorial2 - 1  (0) 2022.01.23
[Swift] 함수 (Functions) (2)  (0) 2022.01.21
[Swift] 프로토콜 (Protocol)  (0) 2022.01.16
[iOS] #available(platform name version, *)  (0) 2022.01.14
[Swift] Control Flow 1-2 - 조건구문 (if, switch, guard)  (0) 2022.01.12