Swift has several small features as a language, many of them being neglected quite often while they consist of small programming gems. One of them is the @discardableResult
attribute that everybody wish they knew from the beginning.
What’s the purpose of @discardableResult
? Put in simple words, when used to annotate a method, then the returned value of the method can be ignored when it gets called.
Let’s make that clear through a basic example. Say that we have the following method that stores the text given as first argument to the file name provided as second argument:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
func save(text: String, to file: String) -> Bool { do { guard let docDirURL = FileManager.default .urls(for: .documentDirectory, in: .userDomainMask).first else { return false } let saveURL = docDirURL .appendingPathComponent(file) .appendingPathExtension(“txt”) try text.write(to: saveURL, atomically: true, encoding: .utf8) return true } catch { return false } } |
This method does nothing more than simply getting the URL to the documents directory, composing the final URL including the file name and the .txt extension, and eventually writing the text to a file.
Even though it is quite straightforward, the above method has two reasons to fail. The first is in case the documents directory URL won’t be returned in the guard
statement shown above. The second is the actual writing to file; we’re calling a method that can throw an exception.
Because of that, the demo method returns false in case it fails to write the text to the file, and true if it manages to do its job successfully.
Making use of the method requires to keep the return value in a local variable or constant:
1 2 3 4 |
let message = “Hello World!” let result = save(text: message, to: “myFile”) |
However, there are cases where we don’t really care about the method’s results. All we need is to call it and just ignore what it brings back. But if we avoid to handle the return value, Xcode will show a warning like the next one. And that can become really annoying if we end up having multiple calls to methods, results of which are being disregarded:
We can partially work that around by replacing the result
constant from the previous snippet with the underscore symbol as follows:
1 2 3 |
_ = save(text: message, to: “myFile”) |
Although simpler than before, it’s still not that elegant. And here is where @discardableResult
comes to give the solution.
All we have to do is to prefix the save(text:to:)
method with that attribute:
1 2 3 4 5 6 |
@discardableResult func save(text: String, to file: String) -> Bool { … } |
Just that! Now we can call it ignoring the return value:
1 2 3 |
save(text: message, to: “myFile”) |
Xcode won’t show any warnings, and definitely the code is more clear now. And the benefit is that we can use the return value if we actually need it.
So, don’t hesitate to use the @discardableResult
attribute with your methods from now on. But be careful! Always think through well first; you don’t want to skip return values from methods that have a crucial role in your code. But regardless of that, it’s a small Swift feature that you will definitely love.