Throwing functions with throws in Swift - Time & Space Complexity
When we use throwing functions in Swift, we want to know how the time to run the code changes as the input grows.
We ask: How does the cost of running a throwing function grow with input size?
Analyze the time complexity of the following code snippet.
func findIndex(of value: Int, in array: [Int]) throws -> Int {
for (index, element) in array.enumerated() {
if element == value {
return index
}
}
throw NSError(domain: "ValueNotFound", code: 1, userInfo: nil)
}
This function searches for a value in an array and throws an error if it is not found.
- Primary operation: Looping through the array elements one by one.
- How many times: Up to the size of the array (n times) in the worst case.
As the array gets bigger, the function may check more elements before finding the value or throwing an error.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | Up to 10 checks |
| 100 | Up to 100 checks |
| 1000 | Up to 1000 checks |
Pattern observation: The number of checks grows directly with the size of the array.
Time Complexity: O(n)
This means the time to run the function grows linearly with the size of the input array.
[X] Wrong: "Throwing an error makes the function slower for all inputs."
[OK] Correct: Throwing an error only happens if the value is not found, so it does not affect the time complexity for successful searches.
Understanding how throwing functions behave helps you explain error handling clearly and shows you can think about performance even when errors occur.
"What if the function searched a sorted array using binary search and still threw errors? How would the time complexity change?"
Practice
throws keyword indicate when used in a Swift function declaration?Solution
Step 1: Understand the role of
Thethrowsthrowskeyword marks a function that can produce an error during execution.Step 2: Recognize error handling requirement
Calling athrowsfunction requires handling the possible error withtryanddo-catch.Final Answer:
The function can produce an error that must be handled. -> Option CQuick Check:
throwsmeans function can throw error [OK]
- Thinking throws means async function
- Assuming throws means function returns Bool
- Confusing throws with access control keywords
Solution
Step 1: Recall correct syntax for throwing functions
In Swift,throwscomes after the parentheses and before the return type.Step 2: Match syntax with options
func fetchData() throws -> String matches the correct syntax:func name() throws -> ReturnType.Final Answer:
func fetchData() throws -> String -> Option DQuick Check:
Correct syntax isthrowsafter () [OK]
- Writing throw instead of throws
- Placing throws after return type
- Omitting throws keyword
enum FileError: Error {
case notFound
}
func readFile() throws -> String {
throw FileError.notFound
}
do {
let content = try readFile()
print(content)
} catch {
print("Error occurred")
}Solution
Step 1: Analyze the throwing function behavior
The functionreadFile()always throwsFileError.notFounderror.Step 2: Understand the do-catch block
ThetrycallsreadFile(), which throws, so control moves tocatchblock printing "Error occurred".Final Answer:
Error occurred -> Option BQuick Check:
Thrown error triggers catch printing message [OK]
- Expecting thrown error value to print
- Ignoring that error causes catch block
- Thinking no output occurs
func riskyOperation() throws -> Int {
return 42
}
let result = riskyOperation()
print(result)Solution
Step 1: Check calling syntax for throwing functions
Calling a function marked withthrowsrequires usingtrykeyword.Step 2: Identify missing try keyword
The code callsriskyOperation()withouttry, causing a compile error.Final Answer:
Missing try keyword when calling riskyOperation() -> Option AQuick Check:
Throwing functions need try when called [OK]
- Calling throws function without try
- Assuming throws means no return value
- Forgetting to handle errors with do-catch
parseNumber(from: String) that throws an error if the string is not a valid integer. Which of the following implementations correctly uses throws and error handling?Solution
Step 1: Check function signature and error throwing
enum ParseError: Error { case invalidFormat } func parseNumber(from text: String) throws -> Int { guard let number = Int(text) else { throw ParseError.invalidFormat } return number } correctly declaresthrowsafter parameters and before return type, and throws error if parsing fails.Step 2: Verify error throwing logic
enum ParseError: Error { case invalidFormat } func parseNumber(from text: String) throws -> Int { guard let number = Int(text) else { throw ParseError.invalidFormat } return number } usesguard letto safely unwrap Int, throwingParseError.invalidFormatif conversion fails.Final Answer:
Correctly implements throwing function with error handling. -> Option AQuick Check:
Throws declared and error thrown on invalid input [OK]
- Not marking function with throws
- Throwing error outside throws function
- Returning default instead of throwing error
Ready to prove it?
Pass the test and this pattern moves unknown
