Generic subscripts let you access parts of a type using flexible keys or indexes that can be different types. This helps write reusable and clear code.
Generic subscripts in Swift
subscript<T>(key: T) -> ValueType {
get {
// return value for key
}
set {
// set value for key
}
}The <T> after subscript means this subscript works with any type T.
You can define get and set blocks to read and write values.
Hashable key but only works if the key is a String. It stores integers in a dictionary.struct Box { var items = [String: Int]() subscript<T: Hashable>(key: T) -> Int? { get { if let key = key as? String { return items[key] } return nil } set { if let key = key as? String, let newValue = newValue { items[key] = newValue } } } }
struct Pair { var first: Int var second: Int subscript<T>(index: T) -> Int? { if let i = index as? Int { switch i { case 0: return first case 1: return second default: return nil } } return nil } }
This program defines a struct with a generic subscript that accepts any key that can be turned into a string. It stores and retrieves integer values using those keys.
struct FlexibleStorage { private var data = [String: Int]() subscript<T: CustomStringConvertible>(key: T) -> Int? { get { let stringKey = key.description return data[stringKey] } set { let stringKey = key.description data[stringKey] = newValue } } } var storage = FlexibleStorage() storage["apples"] = 10 storage[42] = 5 print(storage["apples"] ?? 0) print(storage[42] ?? 0) print(storage["oranges"] ?? 0)
Generic subscripts can make your code more flexible but can also make it harder to understand if overused.
Use constraints like Hashable or CustomStringConvertible to limit what types can be used as keys.
Remember to handle cases where the key type does not match expected types to avoid runtime errors.
Generic subscripts let you use different types as keys or indexes in one subscript.
They help write reusable and flexible code for custom data access.
Use type constraints and safe casting to keep your code clear and safe.
Practice
generic subscripts in Swift?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 AQuick Check:
Generic subscripts = flexible key types [OK]
- Thinking generic subscripts improve speed
- Assuming subscripts only accept integers
- Believing keys auto-convert to strings
Solution
Step 1: Recall generic subscript syntax
Generic subscripts usesubscript<T>(index: T) -> ReturnTypesyntax.Step 2: Check each option
subscript<T>(index: T) -> String { get } matches the correct syntax. func subscript<T>(index: T) -> String { get } wrongly usesfunc. subscript(index: T) -> String { get } misses generic parameter declaration. subscript<T>(index: Int) -> T { get } has mismatched types.Final Answer:
subscript<T>(index: T) -> String { get } -> Option DQuick Check:
Generic subscript syntax = subscript<T> [OK]
- Using func instead of subscript
- Omitting generic parameter <T>
- Mismatching parameter and return types
struct Box {
private var values = [String: Any]()
subscript<T>(key: String) -> T? {
get { values[key] as? T }
set { values[key] = newValue }
}
}
var box = Box()
box["age"] = 30
box["name"] = "Alice"
print(box["age"] as Int?, box["name"] as String?)Solution
Step 1: Understand subscript behavior
The subscript stores values in a dictionary with String keys and Any values, casting on get.Step 2: Analyze stored values and prints
"age" stores 30 (Int), "name" stores "Alice" (String). The print casts them back to Int? and String?, so output shows optionals.Final Answer:
Optional(30) Optional("Alice") -> Option AQuick Check:
Generic subscript returns optional cast values [OK]
- Expecting non-optional output
- Confusing dictionary storage with direct types
- Assuming compilation error due to Any type
struct Container {
private var data = [Int: String]()
subscript<T>(key: T) -> String? {
get { data[key] }
set { data[key] = newValue }
}
}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 CQuick Check:
Subscript key type must match dictionary key type [OK]
- Assuming generic T works without constraints
- Trying to change dictionary type without reason
- Ignoring type mismatch errors
Choose the best approach.
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 BQuick Check:
AnyHashable dictionary + generic subscript = safe flexible keys [OK]
- Using multiple dictionaries instead of one
- Converting all keys to String losing type info
- Force casting keys causing runtime errors
Ready to prove it?
Pass the test and this pattern moves unknown
