我是新来的Swift,我搞不清楚我解包了哪个可选变量,我给它赋了nil,我试着在Playground上调试,但它不让我踩代码。
致命的错误。Unexpectedly found nil while unwrapping an Optional value(解包一个可选值时意外发现nil)
public class ListNode {
public var val: Int
public var next: ListNode?
public init() { self.val = 0; self.next = nil; }
public init(_ val: Int) { self.val = val; self.next = nil; }
public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
}
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
let result = ListNode()
var resultTail = result
var carry: Int = 0
var out: Int = 0
var val1: Int = 0
var val2: Int = 0
var head1: ListNode? = l1
var head2: ListNode? = l2
while (l1 != nil || l2 != nil || carry != 0) {
val1 = head1 != nil ? head1!.val : 0
val2 = head2 != nil ? head2!.val : 0
out = (val1 + val2 + carry) % 10
carry = (val1 + val2 + carry) / 10
resultTail.next = ListNode(out)
resultTail = resultTail.next!
head1 = head1?.next!
head2 = head2?.next!
}
return result.next!
}
}
let node3 = ListNode(3)
let node2 = ListNode(4, node3)
let node1 = ListNode(2, node2)
let node3a = ListNode(5)
let node2a = ListNode(6, node3a)
let node1a = ListNode(4, node2a)
let solution = Solution().addTwoNumbers(node1, node1a)
问候,Farros
如果你搜索 "意外发现nil "错误信息,你会发现几个问题和答案,解释了这意味着什么,并提出了调试技巧。
虽然这个错误的根本原因可能很微妙,但异常的触发器是强行解包了一个可选项,这个可选项是 nil
或引用一个隐式的未包装的可选项,该可选项就是 nil
.
你这里的代码不多,所以不难找到你做这些事情的地方。
你在你的三元操作符中强制解包,也就是在检查了 nil
所以,这不会崩溃
你强行拆开 resultTail.next
和 result.next
但你在这些情况下已经分配了值,所以不会导致崩溃。
最后一个地方是你强制拆包的地方 head1.next
和 head2.next
在你的while循环的底部。 这是一个错误,因为你知道 next
终将 nil
在您的列表末尾。
只需删除 !
会消除异常,但会引入一个新的错误,因为你的 while
循环条件测试初始参数 l1
和 l2
其值永远不会改变。你会冒着无限循环的风险。 我想你的意思是指 head1
和 head2
.
你应该尽量消除所有的强制解包,这并不难。
head1
和 head2
是可选的,所以没有必要强行拆开 next
resultTail
作为一个可选项,并使用有条件的拆包或不拆包。class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
let result = ListNode()
var resultTail: ListNode? = result
var carry = 0
var head1 = l1
var head2 = l2
while (head1 != nil || head2 != nil || carry != 0) {
let val1 = head1?.val ?? 0
let val2 = head2?.val ?? 0
let sum = val1 + val2 + carry
let out = sum % 10
carry = sum / 10
resultTail?.next = ListNode(out)
resultTail = resultTail?.next
head1 = head1?.next
head2 = head2?.next
}
return result.next
}
}
请注意,习惯性的Swift只在编译器不能自动推断出正确的类型或需要与编译器推断出的类型不同的情况下才显式地对变量进行类型化。
你也可以简化和明确你的 ListNode
通过使用命名的参数,并在一个单一的 init
public class ListNode {
public var val: Int
public var next: ListNode?
public init(val: Int = 0, next: ListNode? = nil) {
self.val = val
self.next = next
}
}
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
let result = ListNode()
var resultTail: ListNode? = result
var carry = 0
var head1 = l1
var head2 = l2
while (head1 != nil || head2 != nil || carry != 0) {
let val1 = head1?.val ?? 0
let val2 = head2?.val ?? 0
let sum = val1 + val2 + carry
let out = sum % 10
carry = sum / 10
resultTail?.next = ListNode(val: out)
resultTail = resultTail?.next
head1 = head1?.next
head2 = head2?.next
}
return result.next
}
}
let node3 = ListNode(val:3)
let node2 = ListNode(val: 4, next: node3)
let node1 = ListNode(val: 2, next: node2)
let node3a = ListNode(val:5)
let node2a = ListNode(val: 6, next: node3a)
let node1a = ListNode(val: 4, next: node2a)
let solution = Solution().addTwoNumbers(node1, node1a)