”;
Sometimes developers want to hide the details about the type. So Swift provides two special mechanisms named Opaque Types and Boxed Types. Using these two mechanisms we can manage and abstract the underlying details of types. The opaque type is used to hide the concrete type behind the protocols whereas the boxed type is used to wrap values in a container.
Opaque Type
The opaque type allows us to work with values of a specific type without showing the underlying concrete type. Or we can say that the opaque type is used to hide its return value type. It describes the return value in terms of the protocol it supports rather than showing the concrete type of the function’s return type. It preserves the type identity, which means the Swift compiler can access the type information but the user of the module cannot.
It enhances the abstraction, encapsulation and modularity of the code by hiding the return type of the function or method and showing only the conforms to a certain protocol or structure. In Swift, we are allowed to use opaque return types with generics. Also if a function with opaque type is returned from multiple locations, then all the values returned by that function must have the same type.
We can define opaque type using the some keyword along with the protocol or type.
Syntax
protocol ProtocolName { func methodName() -> String } func functionNAme() -> some ProtocolName { // Implementation that returns a type conforming to the given protocol}
Example
Swift program to demonstrate opaque type.
// Function with return opaque type func randomElement() -> some Equatable{ Int.random(in: 0...14) } let elementOne = randomElement() let elementTwo = randomElement() // Now comparing the first and second elements returned by the function print(elementOne == elementTwo)
Output
It will produce the following output −
false
Example
Swift program to demonstrate opaque type.
// Define a protocol for shapes protocol Shape { func area() -> Double } // Implementing specific shapes struct Rectangle: Shape { let length: Double let breadth: Double func area() -> Double { return length * breadth } } struct Triangle: Shape { let length: Double let height: Double func area() -> Double { return ((length * height) / 2) } } // Function to add areas of two different shapes using opaque type func sumOfArea(rectShape: some Shape, triShape: some Shape) -> Double { return rectShape.area() + triShape.area() } let obj1 = Rectangle(length: 10.2, breadth: 11.0) let obj2 = Triangle(length: 5.1, height: 6.0) let totalArea = sumOfArea(rectShape: obj1, triShape: obj2) print("Total Area is : (totalArea)")
Output
It will produce the following output −
Total Area is : 127.49999999999999
Boxed Protocol Type
A boxed protocol type is used to warp a type that conforms to a protocol inside a container. It generally uses a generic type or existing type like “Any”. It allows us to work with values of different types that share a common protocol without showing the underlying types.
Example
Swift program to demonstrate opaque type.
// Define a protocol protocol Display { func details() -> String } // Implementing for specific types struct Student: Display { var name: String func details() -> String { return "Student''s Name: (name)" } } struct Teacher: Display { var tname: String func details() -> String { return "Teacher''s Name: (tname)" } } // Wrapper type for boxed protocol struct BoxedDisplay { let x: Display init(_ x: Display) { self.x = x } } // Function that accepts a boxed protocol type func displayDetails(box: BoxedDisplay) { print(box.x.details()) } // Instances let obj1 = Student(name: "Monika") let obj2 = Teacher(tname: "Mohit") let box1 = BoxedDisplay(obj1) let box2 = BoxedDisplay(obj2) displayDetails(box: box1) displayDetails(box: box2)
Output
It will produce the following output −
Student''s Name: Monika Teacher''s Name: Mohit
Difference Between Opaque Type and Boxed Protocol Type
Following are the major differences between opaque type and boxed protocol type −
Opaque Type | Boxed Protocol Type |
---|---|
It uses some keyword to create opaque type. | It uses wrapper type to create boxed protocol type. |
It allows function to hide its return type. | It allows function to return a concrete type wrapped in a container. |
It provide type erasure. | It may or may not have type erasure. |
It hides the concrete type. | It warps the specific type. |
”;