Swift의 "some" 키워드

Mar 11 2023
SwiftUI에서 UI 코드 작성을 시작했다면 View의 본문 변수에 있는 "some" 키워드를 확실히 알아차렸을 것입니다. 이 키워드는 Swift에서 제네릭을 표현하는 한 가지 방법입니다. 제네릭은 다형성, 더 구체적으로는 파라메트릭 다형성을 달성하는 데 도움이 될 수 있습니다.

SwiftUI에서 UI 코드를 작성하기 시작했다면 View의 본문 변수에서 "some" 키워드를 확실히 알아차렸을 것 입니다 .

var body: some View { ... }

이 키워드는 Swift에서 제네릭을 표현하는 한 가지 방법입니다. 제네릭은 다형성, 더 구체적으로는 파라메트릭 다형성을 달성하는 데 도움이 될 수 있습니다 . 예를 들면 다음과 같습니다.

struct Company {
  func hire(_ employee: ???) { ... }
}

protocol Employee {
  func doesWork() { ... }
}

struct Accountant: Employee {
  func doesWork() { ... }
}

struct Engineer: Employee {
  func doesWork() { ... }
}

struct UXDesigner: Employee {
  func doesWork() { ... }
}

func hire<E>(_ employee: E) where E: Employee

func hire(_ employee: some Employee)

"일부" 키워드는 어떻게 작동합니까?

"some" 키워드는 불투명한 유형을 나타냅니다 . 우리의 경우 이것은 Employee 프로토콜입니다. Engineer , Accountant 및 UXDesigner는 구체적인 유형 또는 기본 유형을 나타냅니다 . 위에서 배운 것처럼 이것은 이전의 일반 함수와 똑같이 작동합니다. 이 때문에 함수는 하나의 구체적인 유형에 연결되어야 합니다. 예를 들어 다음 코드는 컴파일되지 않습니다.

func hireEmployee(_ candidate: Candidate) -> some Employee {
  if candidate.hasComputerHackingSkills {
   return Engineer()
  }
  
  if candidate.hasNumberSkills {
   return Accountant()
  }
  
  if candidate.hasDesignSkills {
   return UXDesigner()
  }
 }

함수가 불투명한 반환 유형 '일부 직원'을 선언했지만 해당 본문의 반환 문에 일치하는 기본 유형이 없습니다.

이 메서드에서 반환될 수 있는 여러 가지 구체적인(또는 기본) 유형이 있습니다. 이 함수가 작동하려면 모든 return 문이 동일한 기본 유형을 반환하는지 확인해야 합니다. 이렇게 하면 이 코드 조각에 제네릭으로 얻을 수 있는 정적 유형의 성능이 제공됩니다.

이 지식을 가지고 SwiftUI로 돌아가 보겠습니다. 위에서 배운 내용을 통해 이것이 컴파일되지 않는다는 것을 이제 알 수 있습니다.

var makeView: some View {
  if self.showButton {
   return Button("Hello, World") {}
  } else {
   return Text("Hello, World")
  }
 }

@ViewBuilder
var makeView: some View {
  if self.showButton {
    Button("Hello, World") {}
  } else {
    Text("Hello, World")
  }
}

언제 "some" 키워드를 사용하면 안 됩니까?

"some" 키워드를 사용하는 것은 단순하고 일반적인 명령문을 나타내는 좋은 방법입니다. 하지만 옛날 방식을 사용해야 할 때가 있습니다. 예를 들어 메서드 서명에서 불투명한 유형을 여러 번 참조해야 하는 경우 "some" 키워드를 사용하면 작동하지 않습니다. 아래 코드를 참조하십시오.

protocol Employee {
 associatedtype PayStructure: PayType
 func perform(_ work: Work)
}

struct Accountant: Employee {
 typealias PayStructure = AccountantPayStructure
 
 func perform(_ work: Work) { ... }
 
 func getPayStructure<E>(for employee: E) -> E.PayStructure where E: Employee, E.PayStructure == PayStructure {}
}

"some" 키워드를 사용하면 안 되는 또 다른 경우는 일반 유형입니다.

struct PayCheck<Currency> {
  let currency: Currency

  init(currency: Currency) {
    self.currency = currency
  }
}

let paycheck: PayCheck<USD>

요약

우리는 "some" 키워드가 불투명한 유형을 의미하고 Swift 5.7부터 간단한 경우 명명된 제네릭 메서드 서명을 "some" 키워드로 바꿀 수 있음을 배웠습니다. 이렇게 하면 코드가 명확하고 단순해집니다.

읽어 주셔서 감사합니다! 정기적인 Apple 개발 콘텐츠를 보려면 저를 팔로우하세요.