Discover how hiding type details can make your Swift code simpler and safer!
Why Opaque types with some keyword in Swift? - Purpose & Use Cases
Imagine you want to write a function that returns a shape, but you want to hide the exact type of shape it returns. Without opaque types, you might have to reveal the exact type or use a very general type that loses important details.
Manually handling this means either exposing too much detail or losing type information, which can cause bugs or force you to write extra code to check types. It's like giving someone a wrapped gift but telling them exactly what's inside, ruining the surprise and flexibility.
Using the some keyword in Swift lets you return a value of some type that conforms to a protocol without revealing the exact type. This keeps your code flexible and safe, while hiding unnecessary details.
func makeShape() -> Shape { return Circle() }func makeShape() -> some Shape { return Circle() }This lets you write cleaner, safer code by hiding implementation details while keeping strong type guarantees.
Think of a drawing app that returns different shapes but only exposes that it returns some kind of shape, so the app can change shapes internally without breaking other parts of the code.
Opaque types hide exact return types while keeping type safety.
The some keyword makes code more flexible and easier to maintain.
It helps separate what a function does from how it does it.
Practice
some keyword do when used in a Swift function's return type?Solution
Step 1: Understand the purpose of
Thesomekeywordsomekeyword in Swift is used to declare an opaque return type, which means the exact type is hidden but it must conform to a specified protocol.Step 2: Compare with other options
The other options describe behaviors that do not match the opaque type concept: forcing a concrete type, returning any type freely, or allowing multiple types at runtime.Final Answer:
It hides the exact return type but guarantees it conforms to a protocol. -> Option BQuick Check:
Opaque types = hidden concrete type with protocol conformance [OK]
some hides type but keeps protocol rules [OK]- Thinking
someallows any return type without constraints - Confusing
somewith generics - Believing
somereturns multiple types dynamically
View protocol?Solution
Step 1: Identify correct syntax for opaque return type
The correct syntax usessomefollowed by the protocol name without parentheses:-> some View.Step 2: Check each option
func makeView() -> some View { Text("Hello") } matches the correct syntax. func makeView() -> any View { Text("Hello") } usesanywhich is for existential types, not opaque. func makeView() -> View { Text("Hello") } returns the protocol type directly, which is not allowed. func makeView() -> some View() { Text("Hello") } incorrectly adds parentheses afterView.Final Answer:
func makeView() -> some View { Text("Hello") } -> Option AQuick Check:
Opaque type syntax =-> some Protocol[OK]
some without parentheses for opaque types [OK]- Using
anyinstead ofsomefor opaque types - Adding parentheses after protocol name
- Returning protocol type directly instead of opaque type
protocol Shape {
func area() -> Double
}
struct Circle: Shape {
var radius: Double
func area() -> Double { 3.14 * radius * radius }
}
func makeShape() -> some Shape {
Circle(radius: 2)
}
print(makeShape().area())Solution
Step 1: Understand the code flow
The functionmakeShape()returns an opaque type conforming toShape, specifically aCirclewith radius 2.Step 2: Calculate the area
The area of the circle is calculated as 3.14 * 2 * 2 = 12.56.Final Answer:
12.56 -> Option CQuick Check:
Circle area = π * r² = 12.56 [OK]
- Confusing
somewith errors in return type - Using wrong formula for area
- Assuming runtime error due to opaque type
protocol Animal {
func sound() -> String
}
struct Dog: Animal {
func sound() -> String { "Bark" }
}
struct Cat: Animal {
func sound() -> String { "Meow" }
}
func makeAnimal(_ type: String) -> some Animal {
if type == "dog" {
return Dog()
} else {
return Cat()
}
}Solution
Step 1: Understand opaque type restrictions
Functions returningsome Protocolmust always return the same concrete type, even if hidden.Step 2: Analyze the function's return paths
This function returnsDogorCatdepending on input, which breaks the opaque type rule.Final Answer:
Function returns different concrete types violating opaque type rules. -> Option AQuick Check:
Opaque type = single hidden type only [OK]
- Returning different types for opaque return
- Confusing opaque types with protocol types
- Ignoring compiler error about inconsistent return types
Collection protocol, but the collection should be filtered to only even numbers from an input array. Which of these implementations correctly uses some keyword and returns the filtered collection?Solution
Step 1: Understand the requirement
The function must return an opaque type conforming toCollectionthat contains only even numbers filtered from the input.Step 2: Evaluate each option
func evenNumbers(from numbers: [Int]) -> some Collection { numbers.filter { $0 % 2 == 0 } } returns the filtered array usingfilter, which is aCollectionand matches the requirement withsome Collection. func evenNumbers(from numbers: [Int]) -> some Collection { return numbers.map { $0 * 2 } } returns doubled numbers, not filtered evens. func evenNumbers(from numbers: [Int]) -> [Int] { numbers.filter { $0 % 2 == 0 } } returns a concrete array type, not opaque. func evenNumbers(from numbers: [Int]) -> some Collection { return numbers.sorted() } returns sorted numbers but not filtered evens.Final Answer:
func evenNumbers(from numbers: [Int]) -> some Collection { numbers.filter { $0 % 2 == 0 } } -> Option DQuick Check:
Filter evens + opaque return = func evenNumbers(from numbers: [Int]) -> some Collection { numbers.filter { $0 % 2 == 0 } } [OK]
filter and some Collection for opaque filtered result [OK]- Returning wrong filtered or mapped collection
- Returning concrete type instead of opaque
- Not filtering for even numbers
Ready to prove it?
Pass the test and this pattern moves unknown
