Then 파헤치기

kio·2022년 6월 21일
0

Swift

목록 보기
8/11
post-thumbnail

Then 누구냐 넌?

then은 오프소스 프로젝트로써
swift 오픈소스계의 유명인이신 devxou님이 하신 프로젝트입니다.

Then은 클로저를 통한 인스턴스 초기화를 도와주는 pakage입니다.

왜 첫번째 스승은 Then인가?

  1. 우선 유명합니다. 제가 처음 swift 입문했을때부터 사용했고, 그 사용법도 간단합니다.
  2. 코드가 길지 않아 분석하기 편했습니다.....
  3. 현수업사는 사용법은 얘기하지 않을 예정이기에 기존에 검색결과가 많은 스승님을 모시기 위해서 입니다.

그럼 스승님의 가르침을 받아 보겠습니다.
그전에 먼저 https://github.com/devxoul/Then에 가셔서 README를 읽어보세요

파일 구성

Then 3.0.0의 파일구성
위 처럼 then은 테스트 파일과 라이센스, README를 제외하고 파일 하나로 구성되어있다. 따라서, Then.swift 파일을 파헤쳐보겠습니다.

Then의 구현

extension Then where Self: AnyObject {

  @inlinable
  public func then(_ block: (Self) throws -> Void) rethrows -> Self {
    try block(self)
    return self
  }

}

놀라울 정도로 간결하다 한줄 씩 분석해봅세다!

extension Then where Self: AnyObject {

우선 then은 protocol인데 then을 채택한 self는 AnyObject여야한다.

AnyObject란?

"The protocol to which all classes implicitly conform."
즉 모든 클래스를 포함하는 프로토콜이다.
(말 그대로 후뚜루마뚜루에 사용하는 타입을 특정하지 않는 포로토콜인것이다)

두번째 라인,

@inlinable

@inlinable은 함수를 inline으로 만드는 것이다.
@inlinable은 간단한 재귀호출이나 반복문이 적은 함수에 사용하는데, 함수안의 내용이 간단하여 위와같은 방식을 사용한 것으로 추측된다.

inline 함수란?

쉽게 생각하면 함수의 코드를 복사해서 함수가 사용하는데 붙여넣는 방식으로 실행된다고 생각하면 쉽다.
때때로 함수를 실행하는 시간보다 호출하는 시간이 길 수도 있기때문에
위와 같은 방식으로 호출시간을 생략해주는 함수를 말한다.

세번째 라인,

public func then(_ block: (Self) throws -> Void) rethrows -> Self {

우선 then함수는 하나의 함수를 파라미터로 받는다. 이때 함수는 이 프로토콜을 채택한
즉 Anyobject가 된다. 당연히 함수는 throws를 통해 에러가능성을 나타내고 rethrows 또한 해준다. 반환값은 이 함수의 목적에 따라 self가 된다.

throw, throws, rethrows 란?

throw == do, try, catch를 통해 잡힌 에러를 던져주는 명령어
throws == return전에 에러가 나오면 에러객체를 던질 것이다.
rethrows == 나의 파라미터함수가 에러를 뱉을 수 있다.

마지막 함수 내부,

try block(self)
return self

block을 즉 파라미터 함수를 실행시켜준다.
그 후 self를 return!!

이렇게 then함수는 끝이 난다.
간단하지만 작은 귀찮음을 해결하기 좋은 함수인것 같다.

with 과 do

Then에는 then말고도 with과 do 이 두가지 함수가 있는데, 그 형태는 비슷하다.

extension Then where Self: Any {

  @inlinable
  public func with(_ block: (inout Self) throws -> Void) rethrows -> Self {
    var copy = self
    try block(&copy)
    return copy
  }
    
  @inlinable
  public func `do`(_ block: (Self) throws -> Void) rethrows {
    try block(self)
  }

}

차이점 몇개만 짚어볼려고 한다.
우선 공통 사항인

extension Then where Self: Any

then과 다르게 any가 채택할수 있다.

Any와 Anyobject?

이 둘의 차이는 struct를 캐스팅할 수 있는가? 이다
사실은 Anyobject는 모든 인스턴스가 아닌 class type의 인스턴스만 캐스팅할 수 있다.
그에 반해 Any는 진짜 모든 인스턴스가 될 수 있다는거.

let temp = CGRect().then{
	// 잘못된 코드 왜냐하면 cgrect는 struct이다.
}
let temp = CGRect().with{
	//요게 맞는 거지 왜냐하면 with은 any가 다 채택가능하니까!!
}

또 다른점은

public func with(_ block: (inout Self) throws -> Void) rethrows -> Self {
    var copy = self
    try block(&copy)
    return copy
 }

inout이 파라미터에 붙고, 함수 내부에서 copy를 사용한다는 것

inout?

swift는 파라미터가 const형이다. 즉 바꿀수 없다는 것인데 inout을 붙이면 그 값을 수정할 수 있다는 의미가 된다.
쉽게 c++ 에서 파라미터에 &를 붙여서 pass to reference와 같다고 생각하면 쉽다.

그 이외에는 함수 목적에 따라 반환값이 바뀌는 것 뿐 큰 차이는 없다.

오늘의 스승님께 인사

then은 개발을 할 때 귀찮은 한줄 한줄을 줄여주고, snapkit과 함께 했을때, 모든 view들을 선언하고 초기화 하는 과정을 보기 좋게만들어 준다.

then을 공부하면서 inout과 Any와 Anyobject의 명확한 차이를 알게 되어 좋은 시간이었다.
아무래도 현수업사의 최종목표가 깃허브 슈퍼스타이기 때문에 이러한 점을 배워서 기획하면 나도 슈퍼스타가 될 수 있겠...죠?

이로써 첫번째, 현수업사를 마치고 언제나 이쁜말로 해주시는 지적은 정말 저의 또 다른 스승님이 되시니까 언제든지 부탁드립니다.

0개의 댓글