protocol Shape {
func area() -> Double
}
struct Circle: Shape {
var radius: Double
func area() -> Double {
return .pi * radius * radius
}
}
struct Rectangle: Shape {
var width: Double
var height: Double
func area() -> Double {
return width * height
}
}
// Opaque Type 사용
func makeShape() -> some Shape {
return Circle(radius: 5)
}
// 사용
let shape = makeShape()
print(shape.area()) // 78.53981633974483
// protocol 타입과의 차이
// protocol 타입 반환
func makeShape() -> Shape {
return Circle(radius: 5)
}
let shape: Shape = makeShape()
// 위의 코드에서 shape으로 반환되지만 구체적인 타입은 Circle이다
// 제네릭과 Opaque Type의 결합
func makeOpaqueShape<T: Shape>(shape: T) -> some Shape {
return shape
}
let circle = makeOpaqueShape(shape: Circle(radius: 10))
let rectangle = makeOpaqueShape(shape: Rectangle(width: 5, height: 6))
print(circle.area()) // 314.1592653589793
print(rectangle.area()) // 30.0
// 함수가 여러 경로에서 서로 다른 타입을 반환하려고 하면 컴파일 오류가 발생한다
func makeShape(flag: Bool) -> some Shape {
if flag {
return Circle(radius: 5)
} else {
return Rectangle(width: 4, height: 6) // 오류 발생
}
}
Opaque Type은 Swift에서 캡슐화와 성능 최적화를 동시에 제공하는 강력한 도구입니다. 특히, 구현 세부사항을 숨기고 API 설계를 단순화할 때 유용합니다. 다만 반환 타입이 고정된다는 제약이 있으므로, 다형성이 필요한 경우에는 protocol 타입을 고려해야 한다