Swift - Opaque & Boxed Type



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.
Advertisements