@warn_unqualified_access和@warn_unused_result之间的区别?

时间:2021-07-15 22:59:01

Can anyone explain with one example of warn_unqualified_access and warn_unused_result

任何人都可以用warn_unqualified_access和warn_unused_result的一个例子来解释

2 个解决方案

#1


25  

@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 deal a card to a player. You want to pull 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 test your app, you are puzzled. All your players' hands are filled with copies of the same card.

当您测试应用时,您会感到困惑。你所有玩家的手上都装满了同一张牌的副本。

Being new to Swift, you think dropLast modifies deck by removing its last element. Sadly, you are mistaken. It returns a new array containing all but the last element of deck. (Technically it returns an ArraySlice.)

作为Swift的新手,你认为dropLast通过删除它的最后一个元素来修改deck。可悲的是,你错了。它返回一个包含除deck的最后一个元素之外的所有元素的新数组。 (从技术上讲,它返回一个ArraySlice。)

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

编译器和标准库密谋帮助您找出问题所在。 dropLast函数使用@warn_unused_result注释,因此Xcode会在dropLast调用上显示警告:

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

Seeing the warning, you decide to option-click on dropLast and read the documentation, which tells you what dropLast does (returns a new array), and you realize you need to change the line to this:

看到警告,你决定选择 - 点击dropLast并阅读文档,它告诉你dropLast做什么(返回一个新的数组),你意识到你需要将行更改为:

    deck.removeLast()

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

Swift标准库和其他库中的许多函数主要用于返回它们。忽略其中一个函数的返回值通常是一个错误,因此Swift使库作者可以很容易地向用户警告此行为。事实上,Swift可能很快会被修改为默认应用@warn_unused_result,并在函数上使用新的@discardableResult属性来抑制警告。

@warn_unqualified_access

You were so successful with your awesome card game on iOS that you've decided to port it to Mac OS X. On Mac OS X, you use NSView instead of UIView to show things on the screen. You're trying to figure out why your custom CardView is drawing itself incorrectly, so you want to call Swift's standard print function in drawRect:

你在iOS上的精彩纸牌游戏中取得了如此成功,你决定将它移植到Mac OS X.在Mac OS X上,你使用NSView而不是UIView在屏幕上显示内容。你试图找出你的自定义CardView为什么不正确地绘制自己,所以你想在drawRect中调用Swift的标准打印功能:

class CardView: NSView {

    var card: Card

    override func drawRect(dirtyRect: NSRect) {
        print("Drawing \(card)")

        // drawing code here...
    }

    // rest of CardView here...
}

When you run your app, you're surprised to find that it pops up the print dialog! What's going on? The compiler and NSView have conspired to help you figure out the problem. The NSView.print function is annotated with @warn_unqualified_access, so Xcode shows you a warning on the print call:

当您运行应用程序时,您会惊讶地发现它会弹出打印对话框!这是怎么回事?编译器和NSView密谋帮助您找出问题所在。 NSView.print函数使用@warn_unqualified_access注释,因此Xcode会在打印调用上显示警告:

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

Seeing the warning, you option-click on print and read the documentation. You learn that NSView has its own print method, which lets the user print the contents of the view onto paper. How droll! Now you realize you need to change the call to explicitly use Swift's print function like this:

看到警告,您可以选择单击打印并阅读文档。您了解到NSView有自己的打印方法,可让用户将视图内容打印到纸上。怎么可笑!现在您意识到需要更改调用以显式使用Swift的打印功能,如下所示:

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

(It is virtually impossible to develop for Mac OS X in Swift without running into this particular case. Repeatedly.)

(在没有遇到这种特殊情况的情况下,几乎不可能在Swift中为Mac OS X开发。反复。)

This sort of problem is much less common than the other problem of ignoring a function's result. NSView.print is the only case that I can recall running into.

这种问题比忽略函数结果的其他问题要少得多。 NSView.print是我唯一可以回想起来的案例。

#2


5  

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 in C.foo():

一个在C.foo():

warning: use of 'foo' treated as a reference to instance method in class 'C' use 'self.' to silence this warning

警告:使用'foo'作为对'C'类中实例方法的引用,使用'self'。沉默这个警告

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

这是因为我将foo声明为@warn_unqualified_access,因此这意味着编译器希望我在访问所述成员时显式引用该对象。这是因为 - 例如 - 在NSView的子类中调用print在Swift.print和NSView.print之间发生冲突

The second warning is generated in main(), when calling bar:

调用bar时,在main()中生成第二个警告:

warning: result of call to 'bar' is unused c.bar(1)

警告:调用'bar'的结果未使用c.bar(1)

This is because I am calling bar(), declared as @warn_unused_result, and then discarding its result. This is useful, for example, in methods which return you a new value but have no side effects. If you choose to ignore the new value, you essentially wasted work. The compiler can warn you to point that out.

这是因为我调用bar(),声明为@warn_unused_result,然后丢弃其结果。例如,在返回新值但没有副作用的方法中,这很有用。如果您选择忽略新值,则基本上浪费了工作。编译器可以警告您指出这一点。

#1


25  

@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 deal a card to a player. You want to pull 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 test your app, you are puzzled. All your players' hands are filled with copies of the same card.

当您测试应用时,您会感到困惑。你所有玩家的手上都装满了同一张牌的副本。

Being new to Swift, you think dropLast modifies deck by removing its last element. Sadly, you are mistaken. It returns a new array containing all but the last element of deck. (Technically it returns an ArraySlice.)

作为Swift的新手,你认为dropLast通过删除它的最后一个元素来修改deck。可悲的是,你错了。它返回一个包含除deck的最后一个元素之外的所有元素的新数组。 (从技术上讲,它返回一个ArraySlice。)

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

编译器和标准库密谋帮助您找出问题所在。 dropLast函数使用@warn_unused_result注释,因此Xcode会在dropLast调用上显示警告:

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

Seeing the warning, you decide to option-click on dropLast and read the documentation, which tells you what dropLast does (returns a new array), and you realize you need to change the line to this:

看到警告,你决定选择 - 点击dropLast并阅读文档,它告诉你dropLast做什么(返回一个新的数组),你意识到你需要将行更改为:

    deck.removeLast()

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

Swift标准库和其他库中的许多函数主要用于返回它们。忽略其中一个函数的返回值通常是一个错误,因此Swift使库作者可以很容易地向用户警告此行为。事实上,Swift可能很快会被修改为默认应用@warn_unused_result,并在函数上使用新的@discardableResult属性来抑制警告。

@warn_unqualified_access

You were so successful with your awesome card game on iOS that you've decided to port it to Mac OS X. On Mac OS X, you use NSView instead of UIView to show things on the screen. You're trying to figure out why your custom CardView is drawing itself incorrectly, so you want to call Swift's standard print function in drawRect:

你在iOS上的精彩纸牌游戏中取得了如此成功,你决定将它移植到Mac OS X.在Mac OS X上,你使用NSView而不是UIView在屏幕上显示内容。你试图找出你的自定义CardView为什么不正确地绘制自己,所以你想在drawRect中调用Swift的标准打印功能:

class CardView: NSView {

    var card: Card

    override func drawRect(dirtyRect: NSRect) {
        print("Drawing \(card)")

        // drawing code here...
    }

    // rest of CardView here...
}

When you run your app, you're surprised to find that it pops up the print dialog! What's going on? The compiler and NSView have conspired to help you figure out the problem. The NSView.print function is annotated with @warn_unqualified_access, so Xcode shows you a warning on the print call:

当您运行应用程序时,您会惊讶地发现它会弹出打印对话框!这是怎么回事?编译器和NSView密谋帮助您找出问题所在。 NSView.print函数使用@warn_unqualified_access注释,因此Xcode会在打印调用上显示警告:

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

Seeing the warning, you option-click on print and read the documentation. You learn that NSView has its own print method, which lets the user print the contents of the view onto paper. How droll! Now you realize you need to change the call to explicitly use Swift's print function like this:

看到警告,您可以选择单击打印并阅读文档。您了解到NSView有自己的打印方法,可让用户将视图内容打印到纸上。怎么可笑!现在您意识到需要更改调用以显式使用Swift的打印功能,如下所示:

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

(It is virtually impossible to develop for Mac OS X in Swift without running into this particular case. Repeatedly.)

(在没有遇到这种特殊情况的情况下,几乎不可能在Swift中为Mac OS X开发。反复。)

This sort of problem is much less common than the other problem of ignoring a function's result. NSView.print is the only case that I can recall running into.

这种问题比忽略函数结果的其他问题要少得多。 NSView.print是我唯一可以回想起来的案例。

#2


5  

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 in C.foo():

一个在C.foo():

warning: use of 'foo' treated as a reference to instance method in class 'C' use 'self.' to silence this warning

警告:使用'foo'作为对'C'类中实例方法的引用,使用'self'。沉默这个警告

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

这是因为我将foo声明为@warn_unqualified_access,因此这意味着编译器希望我在访问所述成员时显式引用该对象。这是因为 - 例如 - 在NSView的子类中调用print在Swift.print和NSView.print之间发生冲突

The second warning is generated in main(), when calling bar:

调用bar时,在main()中生成第二个警告:

warning: result of call to 'bar' is unused c.bar(1)

警告:调用'bar'的结果未使用c.bar(1)

This is because I am calling bar(), declared as @warn_unused_result, and then discarding its result. This is useful, for example, in methods which return you a new value but have no side effects. If you choose to ignore the new value, you essentially wasted work. The compiler can warn you to point that out.

这是因为我调用bar(),声明为@warn_unused_result,然后丢弃其结果。例如,在返回新值但没有副作用的方法中,这很有用。如果您选择忽略新值,则基本上浪费了工作。编译器可以警告您指出这一点。