Swift 강좌 4 - 함수

Swift / / 2021. 10. 9. 09:33
반응형

원래 함수와 클로저를 다루는 내용이었지만 여기에선 함수만 다룹니다.

클로저 부분은 “A Swift Tour” 문서 내용으로 파악이 힘들어 추후 가이드 문서 볼때 작성하는 것으로 합니다.



A Swift Tour ( https://docs.swift.org/swift-book/GuidedTour/GuidedTour.html ) 문서의 코드를 Swift Playground(https://swiftfiddle.com/ )에서 실행시켜 보며 진행해보았습니다. 

작성한 본 문서는 공부한 내용을 정리하는 목적이며 A Swift Tour 문서의 내용을 바탕으로 하고 있습니다. 잘못된 점이 있을 수 있습니다. 

 

2021. 10. 9  - 최초작성 

2021. 11. 2 -  접속 불가 상태인 Swift Playground 사이트 변경


func 키워드를 사용하여 함수를 다음처럼 선언합니다. 파라미터는 콤마(,)로 구분하여 여러 개가 추가될 수 있습니다.



func 함수이름(파라미터_이름: 파라미터_타입) -> 리턴타입{

 

    return 반환값

}



함수의 아규먼트로 두 개의 문자열을 받아서 문자열에 조합하여 출력하는 예제 코드입니다.

함수의 아규먼트에  이 값을 받을 파라미터 이름을 적어주지 않으면 에러가 발생합니다. 

 

func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}

var ret = greet(person: "Bob", day: "Tuesday")

print(ret)



실행결과

 

Hello Bob, today is Tuesday.



기본적으로 함수는 파라미터 이름을 파라미터의 레이블로 사용합니다. 앞 예제에서 함수 아규먼트 적을때 파라미터 이름을 앞에 적어줘야 했습니다.

 

필요한 경우 파라미터 이름 앞에 사용자 정의 파라미터 레이블을  추가할 수 있습니다. 또는 사용자 정의 파라미터 레이블이 필요없는 경우 _를 적어줄 수 있습니다.

 

다음 예제에서는 파라미터  person을 위한 사용자 정의 파라미터 대신에 _를 추가하고, 파라미터 day를 위한 사용자 정의 파라미터 레이블로 on을 추가했습니다.

 

함수 아규먼트가 앞 예제와 달라졌습니다. 첫번째 파라미터의 사용자 정의 파라미터 레이블로 _을 지정했기 때문에 첫번째 파라미터의 이름을 생략할 수 있게 되었으며( 시험삼아 _를 삭제해보면 에러가 나면서 person:을 추가하라는 메시지가 보입니다.)   두번째 아규먼트에는 파라미터 이름인 day 대신에 사용자 정의 파라미터 레이블로 추가한 on을 사용했습니다. 

 

func greet(_ person: String, on day: String) -> String {
    return "Hello \(person), today is \(day)."
}

var ret = greet("John", on: "Wednesday")

print(ret)

 

실행결과

 

Hello John, today is Wednesday.




튜플을 사용하여 파이썬처럼 여러 값을 하나로 묶을 수 있습니다. 여기에선 괄호안에 리턴할 값을 콤마로 구분하여 적어 튜플을 생성한 후, 함수의  리턴값으로 사용합니다.  

튜플의 요소는 튜플에 포함된 변수/상수 이름이나 튜플의 몇번째 요소인지 나타내는 번호로 참조할 수 있습니다.



func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0

    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }

    return (min, max, sum)
}


let statistics = calculateStatistics(scores: [1, 2, 3])

print(statistics.sum)

print(statistics.0)

 

실행결과

 

6
1



다음 순서로 실행됩니다.

 

1. 함수 calculateStatistics의 아규먼트로 배열 [1, 2, 3]을 넘기면

 

2. 함수 calculateStatistics에선 배열의 첫번째 요소로 변수 min, max를 초기화하고, 합을 저장할 변수 sum는 0으로 초기화합니다.

 

3. 배열 scores의 원소를 하나씩 접근하여  비교를 통해 필요시 변수 max와 min의 값을 업데이트합니다.

 

4. 배열의 요소를 변수 sum에 더해집니다.

 

5. 변수 min, max, sum을 튜플로 묶어서 리턴합니다. 

 

6. 리턴된 튜플 statistics로부터 변수 sum의 값은 statistics.sum로 접근하여 출력합니다.

 

7. 리턴된 튜플 statistics로부터 변수 min의 값을 인덱스 0으로 접근하여 출력합니다. 

    튜플 statistics의 첫번째 요소이기 때문에 인덱스 0으로 접근할 수 있는 것입니다. 




함수는 중첩될 수 있습니다. 다른 함수의 내부에서 정의된 함수는 자신이 선언된 외부 함수에서 선언된 변수에 액세스할 수 있습니다. 

 

다음 예제에서 내부에 선언된 함수 add에서 외부 함수 returnFifteen에서 선언된 변수 y에 접근하여 5를 더하고 있습니다. 

실행결과에서 외부 함수 returnFifteen의 리턴값이 15가 된 것을 볼 수 있습니다. 내부 함수에서 외부 함수의 변수값을 변경한 것이 반영된 것입니다. 

 

func returnFifteen() -> Int {

    var y = 10

    func add() {
        y += 5
    }

    add()

    return y
}

var ret =  returnFifteen()

print(ret)



실행결과

 

15




함수는  first-class 타입입니다. 즉, 함수가 다른 함수를 리턴값으로 반환할 수 있음을 의미합니다.

다음 예제에서는 함수 makeIncrementer에서 내부에 정의된 함수addOne를 반환하고 있습니다.

 

func makeIncrementer() -> ((Int) -> Int) {

    func addOne(number: Int) -> Int {
        return 1 + number
    }

    return addOne
}

var increment = makeIncrementer()

print(increment(7))

 

실행결과

 

8



위 코드에서 함수 makeIncrementer의 파라미터와 아규먼트가 다르게 작성된 것을 볼 수 있습니다. 

함수 makeIncrementer의 리턴 타입적는 부분에  함수 addOne의 파라미터 타입과 리턴 타입을 적어주고 있습니다.

 

또한 함수를 호출하는 부분도 다릅니다. 

 

이 부분들은 공부하는 와중에 확인되면 내용을 추가하겠습니다.




함수는 다른 함수를 아규먼트로 사용하여 호출할 수 있습니다.  

 

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]

print(hasAnyMatches(list: numbers, condition: lessThanTen))



배열 numbers의 값 중에 10보다 작은 수가 있으면 true를 리턴하는 예제 코드입니다.

 

몇가지 특이사항만 살펴보겠습니다. 

 

함수 hasAnyMatches의 아규먼트로 함수 lessThanTen가 사용되고 있습니다. 

함수 hasAnyMatches의 파라미터에서 함수 lessThanTen를 받는 부분엔 타입 자리에  함수 lessThanTen의 파라미터 타입과 리턴 타입을 적어주고 있습니다. 

 

함수 lessThanTen 호출시  파라미터 이름 condition를 사용하는 것을 볼 수 있습니다. 



실행결과

 

true




Swift 강좌 1 - Hello, world

https://webnautes.tistory.com/1549



Swift 강좌 2 - 상수와 변수

https://webnautes.tistory.com/1550



Swift 강좌 3 - 제어문 : if, for - in, switch, repeat - while

https://webnautes.tistory.com/1551



Swift 강좌 4 - 함수

https://webnautes.tistory.com/1552



Swift 강좌 5 - 객체(Objects)와 클래스(Classes)

https://webnautes.tistory.com/1558



Swift 강좌 6 - 열거형(Enumerations)과 구조체(Structures)

https://webnautes.tistory.com/1559



Swift 강좌 7 - 프로토콜(Protocols)과 익스텐션(Extensions)

https://webnautes.tistory.com/1562



Swift 강좌 8 - 에러 처리(Error Handling)

https://webnautes.tistory.com/1566



Swift 강좌 9 - 제네릭(Generics)

https://webnautes.tistory.com/1568



반응형

해보고 확인한 것을 문서화하여 기록합니다.


부족함이 있지만 도움이 되었으면 합니다.
잘못된 부분이나 개선점을 알려주시면 감사하겠습니다.



포스트 작성시에는 문제 없었지만 이후 문제가 생길 수 있습니다.
문제가 생기면 포스트와 바뀐 환경이 있나 먼저 확인해보세요.

질문을 남겨주면 가능한 빨리 답변드립니다.


제가 쓴 책도 한번 검토해보세요 ^^

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

">