📖 Scenario: Imagine you have a collection that stores different types of values, like numbers and words. You want to access these values easily using a special way called a generic subscript.
🎯 Goal: Build a Swift struct called MultiTypeStorage that uses a generic subscript to get and set values of different types by their keys.
📋 What You'll Learn
Create a struct called MultiTypeStorage with a dictionary property named storage of type [String: Any].
Add a generic subscript subscript(key: String) -> T? to get and set values of any type T.
Use the generic subscript to store and retrieve values of different types by their keys.
Print the retrieved values to show the generic subscript works.
💡 Why This Matters
🌍 Real World
Generic subscripts help manage collections that store mixed types, like user settings or configuration data, making code cleaner and safer.
💼 Career
Understanding generic subscripts is useful for Swift developers working on flexible data storage, APIs, or frameworks that handle various data types.
Progress0 / 4 steps
1
Create the MultiTypeStorage struct with a storage dictionary
Create a struct called MultiTypeStorage with a variable storage of type [String: Any] initialized as an empty dictionary.
Swift
Hint
Use struct MultiTypeStorage { var storage: [String: Any] = [:] } to create the struct and dictionary.
2
Add a generic subscript to MultiTypeStorage
Inside MultiTypeStorage, add a generic subscript subscript(key: String) -> T? that gets and sets values in storage. For getting, cast the stored value to T. For setting, assign the new value to storage[key].
Swift
Hint
Use subscript(key: String) -> T? with get and set blocks to access storage.
3
Store values of different types using the generic subscript
Create a variable storage of type MultiTypeStorage. Use the generic subscript to set storage["age"] = 30 and storage["name"] = "Alice".
Swift
Hint
Create var storage = MultiTypeStorage() and assign values using storage["age"] = 30.
4
Retrieve and print values using the generic subscript
Use the generic subscript to get age as Int? and name as String? from storage. Print both values using print(age) and print(name).
Swift
Hint
Retrieve values with let age: Int? = storage["age"] and print them.
Practice
(1/5)
1. What is the main benefit of using generic subscripts in Swift?
easy
A. They allow subscripts to accept different types as keys or indexes.
B. They make subscripts run faster by using fixed types only.
C. They restrict subscripts to only integer indexes.
D. They automatically convert all keys to strings.
Solution
Step 1: Understand generic subscripts purpose
Generic subscripts let you write one subscript that works with many types of keys or indexes.
Step 2: Compare options with this purpose
Only They allow subscripts to accept different types as keys or indexes. correctly states that generic subscripts accept different types as keys or indexes.
Final Answer:
They allow subscripts to accept different types as keys or indexes. -> Option A
4. Identify the error in this generic subscript code and choose the fix:
struct Container {
private var data = [Int: String]()
subscript<T>(key: T) -> String? {
get { data[key] }
set { data[key] = newValue }
}
}
medium
A. Change dictionary to [T: String] to match generic key type.
B. Add type constraint to subscript declaration.
C. Change subscript to subscript(key: Int) -> String? to match dictionary key type.
D. No error; code works as is.
Solution
Step 1: Check dictionary key type vs subscript key type
Dictionary keys are Int, but subscript uses generic T which can be any type.
Step 2: Identify mismatch causing error
Accessing data[key] fails because key is T, not necessarily Int. Fix is to restrict subscript key to Int.
Final Answer:
Change subscript to subscript(key: Int) -> String? to match dictionary key type. -> Option C
Quick Check:
Subscript key type must match dictionary key type [OK]
Hint: Subscript key type must match dictionary key type [OK]
Common Mistakes:
Assuming generic T works without constraints
Trying to change dictionary type without reason
Ignoring type mismatch errors
5. Given a struct that stores values with keys of any Hashable type, how can you implement a generic subscript to safely get and set values? Choose the best approach.
hard
A. Use separate dictionaries for each key type and switch inside the subscript.
B. Use a dictionary with keys of type AnyHashable and cast keys inside the subscript.
C. Use a dictionary with keys of type String only and convert all keys to String.
D. Use a generic dictionary [T: Any] without constraints and force cast keys.
Solution
Step 1: Understand requirement for any Hashable key
To store values with keys of any Hashable type, use a dictionary with keys of type AnyHashable.
Step 2: Implement generic subscript with safe casting
Use generic subscript with key of type T: Hashable, convert key to AnyHashable for dictionary access, ensuring type safety.
Final Answer:
Use a dictionary with keys of type AnyHashable and cast keys inside the subscript. -> Option B