본문 바로가기

iOS 프로그래밍/문법

[swift] 문법정리3 ( 함수와 메서드, 클로저)

함수

함수 정의부의 값을 매개변수 , 호출시의 값은 인수라고 부름

메서드

특정 클래스나 구조체, 또는 열거형과 관련된 함수

스위프트 함수를 선언하는 방법

- 매개변수를 받지 않으며 결과를 반환하지도 않고 오직 메시지만 출력

ex)

func sayHello() {    //리턴값 없으면(Void) 지정하지 않아도 됨
    print("Hello")
} 

- 하나의 문자열과 하나의 정수를 매개변수로 받아서 문자열을 반환

func buildMessage(name: String, count: Int) -> String {
    return("\(name), you are customer number \(count)")
}

 

C언어에서 swift 함수 변경하기

c언어

int add(int x, int y)  {     //C, C++
    return(x+y); 
} 

add(10,20);

swift

func add(x: Int, y: Int) -> Int {
    return(x+y)
} 

add(x:10, y:20)

 

내부 매개변수 이름과 외부 매개변수 이름

함수 호출시 외부 매개변수명 사용

ex)

func add(first x: Int, second y: Int) -> Int { 
    //외부 내부:자료형 
    return(x+y)  
    //함수 정의시 내부 매개변수명 사용 
}

add(first:10, second:20)
//함수 호출시 외부 매개변수명 사용

 

swift 함수 실습

외부매개변수명 생략하는 형태를 많이 쓰기 때문에 외부 매개변수와 내부 매개 변수의 쓰임에 대해 간단한 실습을 해보도록 하겠습니다.

 

외부 매개변수명: 호출할 때 사용

내부 매개변수명: 함수 내부에서 사용

 

func add(x: Int, y: Int) -> Int {
    return(x+y)
}

print(add(x:10, y:20))


func add(first x: Int, second y: Int) -> Int {
    return(x+y)
}

print(add(first:10, second:20))


func add(_ x: Int, _ y: Int) -> Int {
    return(x+y)
}

print(add(10, 20))


func add(_ x: Int, with y: Int) -> Int {
    return(x+y)
}

print(add(10, with:20))

 

디폴트 함수 매개변수 정의하기

인자로 전달하는 값이 없는 상태로 함수가 호출될 때 디폰트 매개변수 값을 사용

 

ex)

func buildMessage(name: String = "Customer", count: Int) -> String {

    return("\(name), you are customer number \(count)")

}

var message = buildMessage(count:100)

print(message)

 

함수로부터 여러 개의 결과 반환하기

- 함수는 여러 결과 값들을 튜플로 감싸서 반환 할 수 있음

func sizeConverter (length: Float) -> (yards: Float, centimeters: Float, meters: Float) {
    let yards = length * 0.0277778 
    let centimeters = length * 2.54 
    let meters = length * 0.0254 
    return (yards, centimeters, meters) 
}

var lengthTuple = sizeConverter(length:20) 

print(lengthTuple.yards) 
print(lengthTuple.centimeters) 
print(lengthTuple.meters)

 

2개의 정수를 입력받아 가감제 리턴

func sss (x : Int, y : Int) -> (sum : Int, sub : Int, div : Double)
{ 
    let sum = x+y 
    let sub = x-y 
    let div = Double(x)/Double(y) 
    return (sum, sub, div) 
} 

var result = sss(x:15,y:14) 

print(result.sum)
print(result.sub) 
print(result.div)

 

함수의 가변 매개변수

- 애플리케이션 코드 내에서 함수가 호출될 때 함수가 받아야 할 매개변수의 개수를 항상 알 수 있는 것은 아님

- 스위프트는 가변 매개변수(variadic paramenter)를 사용하여 해결

- 가변 매개변수는 함수가 지정된 데이터 타입으로 0개 또는 그 이상의 매개변수를 받는다는 것을 가리키기 위해서 세 개의 점(...)을 이용하여 선언

func displayStrings(strings: String...)
{
     for string in strings {
          print(string) 
    } 
} 

displayStrings(strings:"one", "two", "three", "four")

 

In-Out 매개변수로 작업하기

- swift는 기본적으로 call by value

- Objective-C는 기본적으로 call by reference

- 함수가 값을 반환한 후에도 매개변수에 일어난 변화를 유지하려면, 함수의 선언부에서 매개변수를 입출력 매개변수로 선언해야 함

- doubleValue 함수를 수정하여 다음과 값이 inout 키워드를 매개변수에 붙임

- Swift에서 call by reference를 구현하는 방법

- 함수를 호출할 때 입출력 매개변순는 앰퍼샌드(&)를 앞에 붙여주어야 한다.

 

var myValue = 10 

func doubleValue (value: inout Int) -> Int { 
    value += value 
    return(value) 
} 

print(doubleValue(value : &myValue))
// 20

 

매개변수로 함수를 사용

- 스위프트는 함수를 데이터 타입처럼 처리할 수 있음

ex)

func inchesToFeet (inches: Float) -> Float {

    return inches * 0.0833333

}

let toFeet = inchesToFeet //함수를 자료형처럼 사용

ex)

func inchesToFeet (inches: Float) -> Float { 

    return inches * 0.0833333

} 

func inchesToYards (inches: Float) -> Float {

    return inches * 0.0277778 

} 

let toFeet = inchesToFeet 

let toYards = inchesToYards

func outputConversion(_ converterFunc: (Float) -> Float​, value: Float){

    //함수를 매개변수로 사용

    let result = converterFunc(value)

    print("Result of conversion is \(result)")

}

//outputConversion 함수를 호출할 때 선언된 데이터 타입과 일치하는 함수를 전달

//매개변수로 적절한 변환 함수를 전달하면 인치를 피트 또는 야드로 변환하기 위하여

// 동일한 함수가 호출될 수 있음  

outputConversion(toYards, value: 10) //야드로 변환

outputConversion(toFeet, value: 10) //피트로 변환

 

클로저 표현식

- 클로저 표현식은 매개변수를 받거나, 값을 반환하도록 만들 수도 있음

- 클로저 표현식 구문은 함수를 선언하는 것과 비슷

- 다만, 클로저 표현식은 이름을 따로 갖지 않으며, 매개변수와 반환 타입은 중괄호 안에 들어가고, in 키워드는 클로저 표현식 코드가 시작함을 가리키는 데 사용

- 사실, 함수는 이름이 있는 클로저 표현식임

 

ex)

let multiply = {(val1: Int, val2: Int) -> Int in
    return val1 * val2
}

let result = multiply(10, 20) //상수를 함수처럼 호출,200

 

- 클로저 표현식은 비동기 메서드 호출을 위한 완료 핸들러를 선언할 때 종종 사용됨

● iOS 애플리케이션을 개발할 때 요청된 작업이 백그라운드에서 수행되도록 운영체제에 호출하여 애플리케이션이 다른 작업을 계속 수행하도록 해야 할 경우가 종종 있음

● 이런 경우에는 운영체제는 백그라운드에서 수행되는 작업이 완료되었음을 애플리케이션에게 알려줄 것이며, 메서드를 호출할 때 선언한 완료 핸들러를 호출하여 결과를 반환

● 이럴 때 사용하는 완료 핸들러 코드는 주로 클로저 표현식의 형태로 구현

스위프트의 클로저

- 컴퓨터 공학 용어로 클로저(closure)는 보통 독립적인 코드 블록(예를 들어, 함수 또는 클로저 표현식)과 그 코드 블록을 둘러싼 콘텍스트에 존재하는 하나 이상의 변수들의 조합을 의미

func functionA() -> () -> Int { 
    var counter = 0
     func functionB() -> Int {
        return counter + 10
    } 
    return functionB
} 

let myClosure = functionA() 

let result = myClosure()

print(result) // 10

 

- functionB가 counter 변수를 감싸고(captured or closed) 있다고 말할 수 있으므로 전통적인 컴퓨터 공학에서 정의한 클로저로 간주

- 이렇게 클로저와 클로저 표현식이 광범위하게 사용되다 보니 서로의 의미가 혼용되어 사용

- 스위프트에서는 클로저와 클로저 표현식을 모두 지원

참고:

func functionA() -> () -> Int { 
    var counter = 0
     func functionB() -> Int {
        return counter + 10
    } 
    return functionB
} 

let myClosure = functionA()

print(myColosure)