Function

윤주현·2023년 7월 11일

Swift

목록 보기
1/13

Defining and Calling Functions

// Defining functions
func functionName(argumentLabel parameterName: parameterType) -> ReturnType {
}

// Calling Functions
name(argumentLabel: parameter)

examples

// example 1
// 함수를 호출할 때 argument label을 사용해서 가독성을 높일 수 있다.
func greet(to person: String, from hometown: String) -> String {
    return "Hello \(person)!  Glad you could visit from \(hometown)."
    // return for one liners optional
}

greet(to: "Bill", from: "Cupertino")
// "Hello Bill!  Glad you could visit from Cupertino."

// example 2
// argument lable에 "_"을 넣으면 함수를 호출할 때 argument label을 생략하고 파라미터를 전달할 수 있다.
func greet(_ person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet("John", day: "Wednesday")
// "Hello John, today is Wednesday."

// example 3
// 파라미터의 디폴트 값을 지정해 줄 수 있다.
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12) {}
someFunction(parameterWithoutDefault: 3, parameterWithDefault: 6) 
// parameterWithDefault is 6
someFunction(parameterWithoutDefault: 4) 
// parameterWithDefault is 12

Functions As Types

struct Math {
    func addTwoInts(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
    
    func subTwoInts(_ a: Int, _ b: Int) -> Int {
        return a - b
    }
}

모든 함수는 각각 특정 타입을 가지고 있다. 예를 들어 위의 addTwoInts와 subTwoInts는 (Int, Int) -> Int라는 타입으로 표기한다. 이 타입은 두개의 정수를 파라미터로 받아 정수 한 개를 리턴하는 함수라고 해석할 수 있다.

아무 인풋도 아웃풋도 없는 함수의 타입은 () -> Void로 표기한다.

struct Calculator {
    var mathFunction: (Int, Int) -> Int = Math().addTwoInts
}

var calc = Calculator()

// Executed
calc.mathFunction(3, 2) // 5

// And then changed
calc.mathFunction = Math().subTwoInts

// And re-executed
calc.mathFunction(3, 2) // 1

함수는 타입으로 사용할 수 있으니 변수에도 할당할 수 있다. mathFunction 변수는 (Int, Int) -> Int 타입을 가지고 있다.

struct Calculator2 {
    typealias expression = (Int, Int) -> Int
    var mathFunction: expression = Math().addTwoInts
}

typealias를 사용하면 특정 함수 타입에 이름을 붙일 수 있다. 위의 코드에서는 (Int, Int) -> Int 타입에 expression이라는 가명을 붙여 사용할 수 있게 되었다.

func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}

func lessThanTen(number: Int) -> Bool {
    return number < 10
}

var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers, condition: lessThanTen) // true

함수의 파라미터로 함수를 전달받을 수도 있다. hasAnyMatches는 list안의 값들을 condition의 파라미터(Int 타입)에 전달하여 배열 속에 원하는 조건에 맞는 숫자가 있는지 확인하는 함수이다. lessThanTen는 Int -> Bool의 타입을 가지고 있으므로 hasAnyMatches의 condition 파라미터로 전달할 수 있다. 위의 코드에서는 condition 함수가 호출될때 파라미터로 전달된 lessThanTen 함수가 실행이 된다.

인스턴스 메소드 vs 타입 메소드

인스턴스 메소드

일반적으로 사용하는 메소드
인스턴스를 생성해야만 사용 가능(클래스 내에서 사용 불가)
오버라이딩 허용

타입 메소드

static(혹은 class) 키워드가 붙은 메소드
인스턴트를 생성하지 않고도 점 표기법으로 타입명을 통해서 사용 가능.
오버라이딩 허용 X (class 키워드인 경우 서브클래스들은 오버라이딩 가능)

static의 활용

  1. 환경 설정
  2. 메모리를 많이 차지하는 객체
  3. 팩토리 패턴

0개의 댓글