//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,尽管我不能孤立地重现此错误,如果有机会我会仔细看看。

10-07 22:07