我不确定为什么Swift抱怨list1 = list1!.next意外地发现nil,当我的if语句检查list1!= nil时。谁能解释为什么检查list1!= nil是不够的?我已经尝试将其更改为
if list1 {
list1 = list1!.next
}
但它建议我检查使用!= nil
这是我的代码:
class Node {
var data: Int
var next: Node?
init (data: Int) {
self.data = data
}
}
func addReversed (var list1: Node?, var list2: Node?) -> Node {
var carry = 0
var head: Node? = nil
var prev: Node? = nil
while list1 != nil || list2 != nil {
var newNode = addNode(list1, list2, &carry)
appendNode(head, prev, newNode)
if list1 != nil {
list1 = list1!.next
}
if list2 != nil {
list2 = list2!.next
}
}
if carry > 0 {
var carryNode = Node(data: carry)
appendNode(head, prev, carryNode)
}
return head!
}
答案 0 :(得分:0)
这不是你问的问题,但我认为这可能与问题有很大关系。我测试了你的Node和你的基本addReversed
代码,我无法崩溃。但当时我没有任何其他全局功能,所以我不得不在测试时将它们评论出来。由于我没有崩溃,因此我开始相信问题是 其中一个全局函数。
然后你发布了你的要点,包含这些全局函数的代码,我可以立即看到这段代码存在严重缺陷:
func appendNode(var head: Node?, var prev: Node?, node: Node) {
if head == nil {
head = node
}
if prev == nil {
prev = node
}
else {
prev!.next = node
prev = node
}
}
你似乎认为说,例如prev = node
会将prev
中的节点替换为某些外部世界中作为node
的节点。它不会。这些只是局部变量的名称。所以这些代码都没有任何影响 - 除了prev!.next = node
,因为你正在改变外部世界中存在的实例(因为这是一个引用类型,一个类实例)。
如果要将参数中的对象替换为另一个对象,则需要inout
参数。
例如:
class Dog {
let name:String
init(_ s:String) {
name = s
}
}
func replaceDog(var d:Dog) {
d = Dog("Rover") // this is what you are doing
}
var d = Dog("Fido")
replaceDog(d)
d // still Fido
可是:
class Dog {
let name:String
init(_ s:String) {
name = s
}
}
func replaceDog(inout d:Dog) {
d = Dog("Rover")
}
var d = Dog("Fido")
replaceDog(&d)
d // Rover
你的代码充满了同样的错误假设,我认为,虽然我没有弄清楚细节,但这个假设是你在这里遇到困难的原因。我的猜测是你从其他一些有指针的语言中得到了这个链表实现,但是你没有在你的实现中使用指针。在Swift中使用指针的方法是使用inout
!