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