Difference between @warn_unqualified_access and @warn_unused_result?

Can someone explain with one example warn_unqualified_access and warn_unused_result

+7
swift
source share
2 answers

@warn_unused_result

Suppose you have an array representing a deck of cards:

 var deck: [Card] = standardDeck.shuffled() 

You want to write a function to transfer the card to the player. You want to remove the β€œtop” card from the deck, add it to the player’s hand and remove it from the deck:

 func dealCard(to player: Player) { guard let card = deck.last else { fatalError("Ran out of cards") } player.hand.append(card) deck.dropLast() } 

When you are testing your application, you are perplexed. All hands of your players are filled with copies of the same card.

Being new to Swift, you think dropLast modifies the deck by removing its last element. Unfortunately, you are mistaken. It returns a new array containing everything except the last deck element. (Technically, it returns ArraySlice .)

The compiler and the standard library conspired to help you sort out the problem. The dropLast function dropLast annotated with @warn_unused_result , so Xcode shows you a warning when you call dropLast :

 .../Cards.swift:85:10: Result of call to 'dropLast()' is unused 

When you see the warning, you decide to click on the dropLast button and read the documentation that tells you what dropLast doing (returns a new array), and you understand that you need to change the line to this:

  deck.removeLast() 

Many, many functions in the Swift standard library and in other libraries are mainly useful for what they return. Ignoring the return value of one of these functions is usually a mistake, so Swift makes it easier for the author of the library to warn the user about this behavior. In fact, Swift is likely to be changed soon to use @warn_unused_result by default and use the new @discardableResult attribute for the function to suppress the warning.

@warn_unqualified_access

You were so successful at your amazing iOS card game that you decided to port it to Mac OS X. On Mac OS X, you use NSView instead of UIView to show everything on screen. You are trying to understand why your own CardView not draw correctly, so you want to call the standard print Swift function in drawRect:

 class CardView: NSView { var card: Card override func drawRect(dirtyRect: NSRect) { print("Drawing \(card)") // drawing code here... } // rest of CardView here... } 

When you launch the application, you will be surprised to find that it pops up a print dialog! What's happening? The compiler and NSView conspired to help you sort out the problem. The NSView.print function NSView.print annotated with @warn_unqualified_access , so Xcode shows you a warning when calling print :

 .../CardView.swift:95:9: Use of 'print' treated as a reference to instance method in class 'NSView' 

When you see the warning, you can click print and read the documentation. You will learn that NSView has its own print method, which allows the user to print the contents of the view on paper. How funny! Now you understand that you need to change the call to explicitly use the Swift print function as follows:

  Swift.print("Drawing \(card)") 

(It is almost impossible to develop for Mac OS X in Swift without being involved in this particular case.)

Such a problem is much less common than another problem of ignoring the result of a function. NSView.print is the only case I can recall.

+23
source share

Consider the following example:

 class C { @warn_unqualified_access func foo(x: Int) -> Int { return x } @warn_unused_result func bar(x: Int) -> Int { return foo(x) } } func main() { let c = C() c.foo(1) c.bar(1) } main() 

This generates two warnings.

One of C.foo() :

warning: using 'foo' is considered as a reference to an instance method in the class 'C' use 'i'. to disable this warning

This is because I declared foo as @warn_unqualified_access , so this means that the compiler wants me to explicitly refer to the object when accessing the specified member. This is because, for example, calling print in a subclass of NSView conflicts between Swift.print and NSView.print

A second warning is generated in main() when bar is called:

warning: the result of the call to the "bar" is not used c.bar (1)

This is because I call bar() , declared as @warn_unused_result , and then discarding its result. This is useful, for example, in methods that return a new value to you but have no side effects. If you decide to ignore the new value, you essentially wasted the job. The compiler may warn you about this.

+5
source share

All Articles