//generic queue data object
class QNode<T> {
var key: T? = nil
var next: QNode? = nil
}
public class Queue<T> {
//Q1
private var top: QNode<T>! = QNode<T>()
//enqueue the specified object
func enQueue(var key: T) {
//check for the instance
if (top == nil) {
//Q2
top = QNode()
}
//establish the top node
if (top.key == nil) {
top.key = key
return
}
var childToUse: QNode<T> = QNode<T>()
var current: QNode = top
//cycle through the list of items to get to the end.
while (current.next != nil) {
current = current.next! }
//append a new item
childToUse.key = key
current.next = childToUse
}
}
如果将Q1更改为private var top:QNode! = QNode()将提示错误“无法推断出通用参数'T'的参数”,但是在原始代码中Q2可以正常工作而没有错误吗?
最佳答案
这里有一些有趣的行为,因为尽管如此,这归功于类型推断:
var top: QNode<String> = QNode()
和写作一样
var top: QNode<String> = QNode<String>()
或确实
var top: QNode = QNode<String>()
使用!的隐式展开在编译器处创建一些异常行为,尽管它告诉我们它会解释
private var top: QNode! = QNode<T>()
如果我们单击变量名,则其类型为
QNode<T>!
,实际上它的行为与以下行为不同:private var top: QNode<T>! = QNode<T>()
要么
private var top: QNode<T>! = QNode()
在我看来,编译器中的这种混乱像一个错误,因为它应该将
QNode!
视为QNode<T>!
或完全拒绝它。幸运的是,意识到该错误后,您只需使用QNode<T>!
即可解决该错误。我也将这个错误提交给Apple,尽管我不能孤立地重现此错误,如果有机会我会仔细看看。