Opaque Type
A function or method with an opaque return type hides its return value’s type information.
Unlike returning a value whose type is a protocol type, opaque types preserve type identity—the compiler has access to the type information, but clients of the module don’t.
To declares a function/method's return type as opaque use some keyword.
example :
protocol Shape {
func draw() -> String
}
struct Triangle: Shape {
var size: Int
func draw() -> String {
var result: [String] = []
for length in 1...size {
result.append(String(repeating: "*", count: length))
}
return result.joined(separator: "\n")
}
}
struct Square: Shape {
var size: Int
func draw() -> String {
let line = String(repeating: "*", count: size)
let result = Array<String>(repeating: line, count: size)
return result.joined(separator: "\n")
}
}
let smallTriangle = Triangle(size: 3)
struct FlippedShape<T: Shape>: Shape {
var shape: T
func draw() -> String {
let lines = shape.draw().split(separator: "\n")
return lines.reversed().joined(separator: "\n")
}
}
struct JoinedShape<T: Shape, U: Shape>: Shape {
var top: T
var bottom: U
func draw() -> String {
return top.draw() + "\n" + bottom.draw()
}
}
func flip<T: Shape>(_ shape: T) -> some Shape {
return FlippedShape(shape: shape)
}
func join<T: Shape, U: Shape>(_ top: T, _ bottom: U) -> some Shape {
JoinedShape(top: top, bottom: bottom)
}
let opaqueJoinedTriangles = join(smallTriangle, flip(smallTriangle))
print(opaqueJoinedTriangles.draw())
// *
// **
// ***
// ***
// **
// *
If a function with an opaque return type returns from multiple places, all of the possible return values must have the same type. For a generic function, that return type can use the function’s generic type parameters, but it must still be a single type.
example - compile error:
func makeShape(shape : String) -> some Shape { // Function declares an opaque return type, but the return statements in its body do not have matching underlying types
if(shape == "square"){
print("here")
return Square(size : 4)
}else{
return Triangle(size : 4)
}
}
let shape = makeShape(shape: "square")
Differences Between Opaque Types and Generic Types
Generic types let the code that calls a function pick the type for that function’s parameters and return value in a way that’s abstracted away from the function implementation
An opaque type lets the function implementation pick the type for the value it returns in a way that’s abstracted away from the code that calls the function.
Differences Between Opaque Types and Protocol Types
An opaque type refers to one specific type, although the caller of the function isn’t able to see which type.
A protocol type can refer to any type that conforms to the protocol.
Swift can infer associated types, which lets you use an opaque return value in places where a protocol type can’t be used as a return value.
Top comments (0)