在拆开一个Optional值时,意外发现nil(搞不清是哪一部分)。

问题描述 投票:-1回答:1

我是新来的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

ios swift optional
1个回答
-1
投票

如果你搜索 "意外发现nil "错误信息,你会发现几个问题和答案,解释了这意味着什么,并提出了调试技巧。

虽然这个错误的根本原因可能很微妙,但异常的触发器是强行解包了一个可选项,这个可选项是 nil 或引用一个隐式的未包装的可选项,该可选项就是 nil.

你这里的代码不多,所以不难找到你做这些事情的地方。

你在你的三元操作符中强制解包,也就是在检查了 nil所以,这不会崩溃

你强行拆开 resultTail.nextresult.next 但你在这些情况下已经分配了值,所以不会导致崩溃。

最后一个地方是你强制拆包的地方 head1.nexthead2.next 在你的while循环的底部。 这是一个错误,因为你知道 next 终将 nil 在您的列表末尾。

只需删除 ! 会消除异常,但会引入一个新的错误,因为你的 while 循环条件测试初始参数 l1l2 其值永远不会改变。你会冒着无限循环的风险。 我想你的意思是指 head1head2.

你应该尽量消除所有的强制解包,这并不难。

  • 使用... 无凝聚运算符 而不是三元
  • head1head2 是可选的,所以没有必要强行拆开 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)
© www.soinside.com 2019 - 2024. All rights reserved.