任何人都可以使用warn_unqualified_access
和warn_unused_result
答案 0 :(得分:31)
@warn_unused_result
假设你有一个代表一副牌的数组:
var deck: [Card] = standardDeck.shuffled()
你想写一个功能来将牌交给玩家。你想从牌组中拉出“顶级”牌,将其添加到玩家手中,然后将其从牌组中移除:
func dealCard(to player: Player) {
guard let card = deck.last else { fatalError("Ran out of cards") }
player.hand.append(card)
deck.dropLast()
}
当您测试应用时,您会感到困惑。所有玩家的手上都装满了同一张牌的副本。
作为Swift的新手,您认为dropLast
通过删除其最后一个元素来修改deck
。可悲的是,你错了。它返回一个 new 数组,其中包含deck
的最后一个元素。 (从技术上讲,它返回ArraySlice
。)
编译器和标准库密谋帮助您找出问题所在。 dropLast
功能使用@warn_unused_result
进行了注释,因此Xcode会在dropLast
来电时向您显示警告:
.../Cards.swift:85:10: Result of call to 'dropLast()' is unused
看到警告,您决定按住dropLast
选项并阅读文档,该文档告诉您dropLast
做了什么(返回一个新数组),并且您意识到需要更改该行对此:
deck.removeLast()
Swift标准库和其他库中的许多函数主要用于返回它们。忽略其中一个函数的返回值通常是一个错误,因此Swift使库作者可以轻松地警告用户此行为。实际上,Swift will probably soon be modified默认情况下应用@warn_unused_result
,并在函数上使用新的@discardableResult
属性来抑制警告。
@warn_unqualified_access
你在iOS上的精彩纸牌游戏非常成功,你决定将它移植到Mac OS X.在Mac OS X上,你使用NSView
而不是UIView
来显示屏幕。您试图找出自定义CardView
错误的原因,因此您想在print
drawRect:
函数
class CardView: NSView {
var card: Card
override func drawRect(dirtyRect: NSRect) {
print("Drawing \(card)")
// drawing code here...
}
// rest of CardView here...
}
当您运行应用程序时,您会惊讶地发现它会弹出打印对话框!这是怎么回事?编译器和NSView
密谋帮助您找出问题所在。 NSView.print
功能使用@warn_unqualified_access
进行了注释,因此Xcode会在print
来电时向您显示警告:
.../CardView.swift:95:9: Use of 'print' treated as a reference to instance method in class 'NSView'
看到警告,您可以选择print
并阅读文档。您了解到NSView
有自己的print
方法,该方法允许用户将视图内容打印到纸上。怎么可笑!现在您意识到需要更改调用以显式使用Swift的print
函数,如下所示:
Swift.print("Drawing \(card)")
(在没有遇到这种特殊情况的情况下,几乎不可能在Swift中为Mac OS X开发。反复。)
这种问题比忽略函数结果的其他问题要少得多。 NSView.print
是唯一一个我记得碰到的案例。
答案 1 :(得分:5)
考虑以下示例:
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()
这会产生两个警告。
C.foo()
中的一个:
警告:使用'foo'作为对'C'类中实例方法的引用 使用'自我'。沉默这个警告
这是因为我声明了foo
as @warn_unqualified_access
,所以这意味着编译器希望我在访问所述成员时显式引用该对象。这是因为 - 例如 - 在print
和NSView
之间的Swift.print
子类中调用NSView.print
调用bar时,main()
会生成第二个警告:
警告:调用'bar'的结果未使用c.bar(1)
这是因为我正在调用bar()
,声明为@warn_unused_result
,然后丢弃其结果。例如,在返回新值但没有副作用的方法中,这很有用。如果您选择忽略新值,则基本上浪费了工作。编译器可以警告你指出这一点。