Hone logo
Hone
Problems

Mastering Defer: Resource Management in Go

Go's defer statement is a powerful tool for ensuring that certain code is executed at a specific point, typically for cleanup operations. This challenge will test your understanding of defer by having you implement resource management scenarios where cleanup is crucial. Mastering defer is essential for writing robust and reliable Go applications, especially when dealing with files, network connections, or locks.

Problem Description

Your task is to write a Go program that demonstrates the correct usage of the defer statement for resource management. You will create functions that simulate opening and closing resources, and you must ensure that the closing operation is always executed, even if errors occur.

Requirements:

  1. Simulate Resource Operations: Create two functions:

    • openResource(resourceName string): This function should simulate opening a resource. It should print a message like "Opening resource: [resourceName]" and return a simple boolean true to indicate success. For this challenge, you don't need to return an actual resource handle.
    • closeResource(resourceName string): This function should simulate closing a resource. It should print a message like "Closing resource: [resourceName]".
  2. Utilize Defer for Cleanup: In a main or helper function, call openResource and then use defer to schedule the call to closeResource with the same resourceName.

  3. Handle Potential Errors (Simulated):

    • Modify openResource to optionally return an error. For instance, if resourceName is "database connection", it should always return an error. If resourceName is "file", it should succeed.
    • Ensure that your defer statement still executes closeResource even when openResource returns an error.
  4. Demonstrate Order of Execution: Show that deferred functions are executed in LIFO (Last-In, First-Out) order. This can be demonstrated by deferring multiple calls.

Examples

Example 1: Successful Resource Opening and Closing

Input: "network connection"
Output:
Opening resource: network connection
Closing resource: network connection

Explanation: The openResource function is called and successfully opens the "network connection". Immediately after the openResource call completes, the deferred closeResource function is scheduled. Since openResource did not return an error, the program continues, and upon exiting the scope where defer was used, closeResource is executed.

Example 2: Resource Opening Fails, but Close Still Executes

Input: "database connection"
Output:
Opening resource: database connection
Error opening resource: database connection: simulated error
Closing resource: database connection

Explanation: The openResource function is called with "database connection". This specific resource name is programmed to always return an error. The openResource function prints its opening message, then returns an error. The error is handled, and a message is printed. Crucially, because closeResource was deferred, it is still executed when the scope is exited, ensuring cleanup.

Example 3: Multiple Deferrals (LIFO Order)

Input: (None, internal demonstration)
Output:
First defer execution
Second defer execution
Third defer execution

Explanation: This example demonstrates the LIFO nature of defer. If you defer three functions: defer func1(), defer func2(), defer func3(), they will execute in the order: func3(), func2(), func1().

Constraints

  • The simulated resource names will be strings.
  • The openResource function should accept a string and return (bool, error).
  • The closeResource function should accept a string and return void.
  • Your solution should be a single Go program that can be compiled and run.
  • Focus on demonstrating defer behavior, not complex error handling logic.

Notes

  • Consider how defer can be used to clean up resources in functions that might have multiple return points (e.g., due to early returns on error).
  • Think about what happens to deferred function arguments. Are they evaluated immediately or when the function is called?
  • This exercise is about understanding the guaranteed execution of deferred calls.
Loading editor...
go