What is @discardableResult

Swift OBjective-C Semantic

In Swift, if you call a function that returns a result, but you don't use it, you would get a compiler warning.

func sum(a: Int, b: Int) -> Int {
return a + b

sum(a: 1, b: 2) // Result of call to 'sum(a:b:)' is unused

You would get the following warning:

Result of call to 'sum(a:b:)' is unused

This is a good warning because when you call a method that returning result, it's unlikely that you would execute that method and then discard the result. This warning helps us catch bugs due to the accidental omission of code that consumes results.

@discardableResult #

@discardableResult is the Swift attribute[1] use to suppress the "Result unused" warning.

You apply @discardableResult to a method like this:

@discardableResult func sum(a: Int, b: Int) -> Int {
return a + b

sum(a: 1, b: 2) // No longer produce the warning

Why should I suppress this warning? #

Even this is a good warning; there might be a time where it is acceptable not to use returned results from methods.

The following are some examples.

In Swift Array, most of mutating collection methods are @discardableResult.

@discardableResult mutating func removeLast() -> Element

removeLast()[2] removes and returns the last element of the collection.

Another example is dump(_:name:indent:maxDepth:maxItems:)[3] which dumps the given object’s contents using its mirror to standard output.

@discardableResult func dump<T>(_ value: T, name: String? = nil, indent: Int = 0, maxDepth: Int = .max, maxItems: Int = .max) -> T

What these methods have in common is they are primarily executed for their side effects although they also provide a return value. These methods shouldn't generate a warning as return value use is optional.

Having an ability to suppress this warning gives an extra clue about the intention of the return value. We can convey a more explicit message to anyone who consumes the method.

Example #

A real-world example that I can think of is an API request method. In the following example, I have a method that executes to fetch a list of users. A caller would execute this for side effects, which is getting a result from the network request. This method return URLSessionTask. If callers want to cancel this operation, they can do it with the returned value, but this is totally optional.

This is a perfect case for @discardableResult.

func getUsers(result: Result<[User], Error>) -> URLSessionTask {
let url = URL(string: "https://example.com/api/users")!
var request = URLRequest(url: url)
request.httpMethod = "GET"

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Handle a response

return task

Objective-C #

In Objective-C, you won't see a warning for unused returned result, but you opt-in by adding __attribute__((warn_unused_result)) directive[4] to a method.

- (NSString *)greeting __attribute__((warn_unused_result));

Conclusion #

The discardable result is an attribute to suppress the "Result unused" warning. It introduced for a subset of methods that are primarily executed for their side effects, although they also provide a return value. These methods should not generate a warning as return value use is truly optional.

Real-world situations where it makes sense to discard non-Void results are rare, but if you have a case where it makes sense, @discardableResult would make your intention clearer to others.

  1. An attribute provides additional information about the declaration or type. https://docs.swift.org/swift-book/ReferenceManual/Attributes.html ↩︎

  2. https://developer.apple.com/documentation/swift/array/2885764-removelast ↩︎

  3. https://developer.apple.com/documentation/swift/1539127-dump ↩︎

  4. The __attribute__ directive is used to decorate a code declaration in C, C++ and Objective-C programming languages. This gives the declared code additional attributes that would help the compiler incorporate optimizations or elicit useful warnings to the consumer of that code. https://blog.twitter.com/engineering/en_us/a/2014/attribute-directives-in-objective-c.html ↩︎

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy this article, you can subscribe to the weekly newsletter.

Every Friday, you’ll get a quick recap of all articles and tips posted on this site — entirely for free.

← Home