Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

브래의 슬기로운 코딩 생활

6 - 1급 객체(first class object), 1급 시민(first class citizen), 클로저(Closure) 본문

2 - 겨울방학/Swift 복습

6 - 1급 객체(first class object), 1급 시민(first class citizen), 클로저(Closure)

김브래 2023. 12. 28. 17:50

first class object : (1)함수를 변수에 저장 가능

Swift는 함수를 데이터 타입처럼 처리할 수 있음
 
다음과 같이 함수를 상수 또는 변수에 할당하는 것이 가능

func inchesToFeet (inches: Float) -> Float {

  return inches * 0.0833333

}

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

 

함수를 호출하려면 원래의 함수 이름 대신에 상수 이름을 이용하여 호출 가능
 
print(inchesToFeet(inches:10))

print(toFeet(10))   //: 매개변수명(inches:) 안씀


first class object : (2) 함수를 매개변수로 사용

func inchesToFeet (inches: Float) -> Float {

  return inches * 0.0833333

}

let toFeet = inchesToFeet

 

함수의 데이터 타입 (자료형): (Float) -> Float  // (매개변수형) -> 리턴형

 

매개변수로 함수를 받으려면, 함수를 받게 될 함수는 함수의 데이터 타입을 선언

func outputConversion(converterFunc: (Float) -> Float, value: Float) {//함수를 매개변수로 사용

   let result = converterFunc(value)  //toFeet(10)

   print("Result = \(result)")

}

outputConversion(converterFunc:toFeet, value: 10) // 피트로 변환하는 inchesToFeet함수 호출


first class object : (3) 함수를 리턴값으로 사용

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 = \(result)")

}

 

outputConversion 함수를 호출할 때 선언된 데이터 타입과 일치하는 함수를 전달
매개변수로 적절한 변환 함수를 전달하면 인치를 피트 또는 야드로 변환하기 위하여 동일한 함수가 호출될 수 있음

outputConversion(converterFunc:toYards, value: 10) // 야드로 변환하는  inchesToYards함수 호출

outputConversion(converterFunc:toFeet, value: 10) // 피트로 변환하는 inchesToFeet함수 호출

 

반환 타입으로 함수의 타입을 선언하면 함수도 반환될 수 있음
다음 함수는 Boolean 매개변수의 값에 따라 toFeet 함수 또는 toYards 함수를 반환

func decideFunction (feet: Bool) -> (Float) -> Float

{                                 //매개변수형   리턴형이 함수형            

  if feet {

    return toFeet   //함수를 리턴

  } else {

    return toYards

  }

}


함수 : 일급 객체 실습

func up(num: Int) -> Int {

   return num + 1

}

 

func down(num: Int) -> Int {

   return num - 1

}

 

let toUp = up        

print(up(num:10))

print(toUp(10))

let toDown = down    

                     

func upDown(Fun: (Int) -> Int, value: Int) { 

   let result = Fun(value)

   print("결과 = \(result)")

}

upDown(Fun:toUp, value: 10)   //toUp(10)

upDown(Fun:toDown, value: 10) //toDown(10)

 

func decideFun(x: Bool) -> (Int) -> Int {                    

                       //매개변수형  리턴형이 함수형            

  if x {

    return toUp  

  } else {

    return toDown

  }

}

let r = decideFun(x:true) // let r = toUp

print(type(of:r))  //(Int) -> Int

print(r(10))  // toUp(10)


클로저(Closure)


클로저 표현식

익명함수
C, C++, Objective-C의 block
Java의 Lambda function
C#의 Delegates
클로저 표현식은 독립적인 코드 블록

 

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

  return(x+y)

}

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

 

let add1 = { (x: Int, y: Int) -> Int in

  return(x+y)

}

//print(add1(x:10, y:20)) //주의 error: extraneous(관련 없는) argument labels 'x:y:' in call

 

print(add1(10, 20))     //OK

print(type(of:add1))    //(Int, Int) -> Int

 

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

{(<매개변수 이름>: <매개변수 타입>, … ) -> <반환 타입> in

   // 클로저 표현식 코드

}

 

두 개의 정수 매개변수를 받아서 정수 결과 값을 반환

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

                            //매개변수         리턴형

        return val1 * val2

} // 여기서 multiply자료형은 (Int, Int) -> Int

 

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


후행 클로저(trailing closure)

클로저가 함수의 마지막 argument라면 마지막 매개변수명(cl)을 생략한 후 함수 소괄호 외부에 클로저를 작성

func someFun(cl: () -> Void) {

}

// trailing closure를 사용 안하면

someFun(cl: {

  //closure’s body

})

// trailing closure 사용

someFun() {

  //trailing closure's body goes here

}

 

클로저가 함수의 마지막 argument라면 마지막 매개변수 이름(handler:)을 생략한 후 함수 소괄호 외부에 클로저를 구현

let onAction = UIAlertAction(title: "On", style:

 UIAlertAction.Style.default) {

   ACTION in self.lampImg.image = self.imgOn

   self.isLampOn=true

}

 

let removeAction = UIAlertAction(title: "제거", style:

  UIAlertAction.Style.destructive, handler: {

    ACTION in self.lampImg.image = self.imgRemove

    self.isLampOn=false

})


클로저의 축약 표현들

func math(x: Int, y: Int, cal: (Int, Int) -> Int) -> Int {

    return cal(x, y)

}

 

let add = {(val1: Int, val2: Int) -> Int  in

        return val1 + val2

}

 

result = math(x: 10, y: 20, cal: add)

 

클로저

 

result = math(x: 10, y: 20, cal: {(val1: Int, val2: Int) -> Int  in

        return val1 + val2

}) //클로저 소스를 매개변수에 직접 작성

 

result = math(x: 10, y: 20, cal: {(val1: Int, val2: Int)   in

        return val1 + val2

}) //리턴형 생략

 

result = math(x: 10, y: 20, cal: {

        return $0 + $1

}) //매개변수 생략하고 단축인자(shorthand argument name)사용

 

result = math(x: 10, y: 20, cal: {

         $0 + $1

}) //클로저에 리턴값이 있으면 마지막 줄을 리턴하므로 return생략

 

후행 클로저

 

result = math(x: 10, y: 20) {(val1: Int, val2: Int) -> Int  in

        return val1 + val2

} //trailing closure

 

result = math(x: 10, y: 20) {(val1: Int, val2: Int)  in

        return val1 + val2

} //trailing closure, 리턴형 생략

 

result = math(x: 10, y: 20) {

        return $0 + $1

} //trailing closure, 매개변수 생략하고 단축인자사용

 

result = math(x: 10, y: 20) { $0 + $1 } //return 생략