What is Opaque type in Swift?

Have you ever seen a wrapped gift box with lots of goodies in it? You know that they’re yummy, but can you say the type or kind of goodies that are contained in this box? No! Opaque type is just like this wrapped gift box that is hiding the type or kind of goodies contained in it.

Defining an Opaque return type

According to Swift’s documentation, when a function or method has an opaque return type, it “hides its return value’s type information.” Rather than provide a concrete type for the function’s return type, the return value is described in terms of the protocols it supports with the keyword “some.”

Difference between opaque return type and protocol return type

Returning an opaque type and protocol type in a function or method is similar, But these two return types differ in the type identity they preserve.

An opaque type refers to one specific type even though the caller of the function can’t see the type, while a protocol type can refer to any type that conforms to the protocol.

Check the example below to better understand how to declare a function with an opaque type and how it works.

Note: Run it on your Playground.

func makeInteger() -> some Equatable{ // create a function that returns some Equatable
Int.random(in: 0...10)
}
let firstInteger = makeInteger()
let secondInteger = makeInteger()
// comparing the firstInteger and secondInteger return type
print(firstInteger == secondInteger) // this returns a result "false" because they are of the same return type else, Xcode will scream at us.

In Example 1, we were able to compare the first integer with the second integer because the function operation deals with an Int type, and the function determines the return type. Now let’s try to compare the variable of the makeInteger function to a variable of the makeString function below.

// create another function that returns some Equatable
func makeInteger() -> some Equatable{
Int.random(in: 0...10)
}
func makeString() -> some Equatable{
"A String"
}
let firstInteger = makeInteger()
let firstString = makeString()
// now compare the value of the firstString to that of the firstInteger from Example 1.
print(firstInteger == firstString)
// Xcode would scream at us even though they both have some equatable as their return type.

Opaque type allows us to do several things:

  1. It allows us to abstract private internal types from the outside world.
  2. Our functions get to decide what type of data gets returned.
  3. It helps us not to worry about Self or associated type requirements because the compiler knows exactly what type is inside.

Opaque type becomes handier when you apply it often. To read more on opaque type, check the Swift documentation.

Free Resources