🔥 프로토콜 준수 여부 확인하기
Swift에서는 is
와 as
연산자를 사용하여 프로토콜 준수 여부를 확인하고, 특정 프로토콜로 캐스팅할 수 있습니다. 프로토콜에 대한 확인 및 캐스팅은 Type Casting에서 설명한 유형에 대한 확인 및 캐스팅과 정확히 동일한 구문을 따릅니다.
is
연산자는 인스턴스가 프로토콜을 준수하면true
를 반환하고, 그렇지 않으면false
를 반환합니다.as?
버전의 다운캐스트 연산자는 프로토콜 유형의 옵셔널 값을 반환하며, 인스턴스가 해당 프로토콜을 준수하지 않으면 이 값은nil
입니다.as!
버전의 다운캐스트 연산자는 프로토콜 유형으로 다운캐스트를 강제로 수행하며, 다운캐스트가 성공하지 않으면 런타임 오류가 발생합니다.
다음 예제에서는 HasArea
라는 프로토콜을 정의하며, 이 프로토콜은 area
라는 이름의 읽기 가능한 Double
속성을 요구합니다.
protocol HasArea { var area: Double { get } }
swift
다음은 HasArea
프로토콜을 준수하는 Circle
과 Country
두 개의 클래스입니다.
class Circle: HasArea { let pi = 3.1415927 var radius: Double var area: Double { return pi * radius * radius } init(radius: Double) { self.radius = radius } } class Country: HasArea { var area: Double init(area: Double) { self.area = area } }
swift
Circle
클래스는 저장 속성인 radius
를 기반으로 계산 속성으로 area
속성 요구사항을 구현합니다. Country
클래스는 저장 속성으로 직접 area
요구사항을 구현합니다. 두 클래스 모두 HasArea
프로토콜을 올바르게 준수합니다.
다음은 HasArea
프로토콜을 준수하지 않는 Animal
이라는 클래스입니다.
class Animal { var legs: Int init(legs: Int) { self.legs = legs } }
swift
Circle
, Country
, Animal
클래스는 공유 기본 클래스를 가지고 있지 않습니다. 그럼에도 불구하고 모두 클래스이므로 세 가지 유형의 인스턴스를 모두 사용하여 AnyObject
유형의 값을 저장하는 배열을 초기화할 수 있습니다.
let objects: [AnyObject] = [ Circle(radius: 2.0), Country(area: 243_610), Animal(legs: 4) ]
swift
objects
배열은 반지름이 2인 Circle
인스턴스, 영국의 표면적(제곱 킬로미터)으로 초기화된 Country
인스턴스, 다리가 4개인 Animal
인스턴스를 포함하는 배열 리터럴로 초기화됩니다.
이제 objects
배열을 반복하고, 배열의 각 객체가 HasArea
프로토콜을 준수하는지 확인할 수 있습니다.
for object in objects { if let objectWithArea = object as? HasArea { print("Area is \(objectWithArea.area)") } else { print("Something that doesn't have an area") } } // Area is 12.5663708 // Area is 243610.0 // Something that doesn't have an area
swift
배열의 객체가 HasArea
프로토콜을 준수할 때마다 as?
연산자가 반환하는 옵셔널 값은 objectWithArea
라는 상수로 옵셔널 바인딩을 통해 언래핑됩니다. objectWithArea
상수는 HasArea
유형으로 알려져 있으므로 area
속성에 안전하게 액세스하여 출력할 수 있습니다.
캐스팅 프로세스에 의해 기본 객체가 변경되지 않는다는 점에 유의하세요. 객체는 여전히 Circle
, Country
, Animal
입니다. 그러나 objectWithArea
상수에 저장되는 시점에는 HasArea
유형으로만 알려져 있으므로 area
속성에만 액세스할 수 있습니다.
위의 다이어그램은 objects
배열의 각 객체에 대해 HasArea
프로토콜 준수 여부를 확인하고, 프로토콜을 준수하는 경우 objectWithArea
상수에 할당하여 area
속성에 접근하는 과정을 보여줍니다. 프로토콜을 준수하지 않는 경우에는 해당 메시지를 출력합니다.
이처럼 프로토콜은 다양한 유형의 객체를 공통의 인터페이스로 처리할 수 있게 해주는 강력한 기능입니다. is
와 as
연산자를 사용하여 프로토콜 준수 여부를 확인하고 캐스팅함으로써 코드의 유연성과 재사용성을 높일 수 있습니다.