链表中的可选节点

时间:2018-03-08 04:56:05

标签: swift linked-list optional

我正在练习斯威夫特语言。 我在xcode中解决了与playground相关的Leetcode问题。

我对链接列表中的可选值进行约束和绑定感到困惑。

这是我的代码。

     // Definition for singly-linked list.
      public class ListNode {
          public var val: Int
          public var next: ListNode?
          public init(_ val: Int) {
              self.val = val
              self.next = nil
          }
      }

    var l1 = ListNode(2)
    l1.next  = ListNode(4)
    //first error: here I have an error that editor explains "Value of optional type 'ListNode?' not unwrapped; did you mean to use '!' or '?'?"
    l1.next.next = ListNode(3)




    //second warning : editors explains that Comparing non-optional value of type 'ListNode' to nil always returns true
    while l1 != nil{
        print(l1.val)
        if let nextNode = l1.next{
            l1 = nextNode
        }
    }

第一个错误,如果我放!对于展开,它仍然显示错误。

  

l1.next!的.next! = ListNode(3)或l1.next.next! = ListNode(3)

我以为我可以展开,因为我确信我为第二个节点设置了正确的节点。

我也尝试了这个

    var l1 = ListNode(2)
    l1.next?  = ListNode(4)
    l1.next!.next? = ListNode(3)

然后我会得到

  

执行被中断,原因是:EXC_BAD_INSTRUCTION   (code = EXC_I386_INVOP,subcode = 0x0)。

请让我理解正确使用可选表达式。

3 个答案:

答案 0 :(得分:1)

你在这里收到错误

0- 1, 1 and a,a 
1- 2,2 and b,b and c,c 
2- null

由于foreach(string_data[0] as $value){ } //first error: here I have an error that editor explains "Value of optional type 'ListNode?' not unwrapped; did you mean to use '!' or '?'?" l1.next.next = ListNode(3) l1.next类型,因此它可能为零。所以它不允许你两次分配Optional而不打开它。

ListNode

第二种情况

.next

<强> EDIT2

l1.next?.next = ListNode(3)

此处while l1 != nil{ print(l1.val) if let nextNode = l1.next{ l1 = nextNode } } 不是可选的。 var node = l1.next while node != nil { print (node.value) node = node.next } 是可选的,因此您应该

使用l1循环下一个元素。否则这里不需要循环

修改

为什么l1.next会造成崩溃?

首先,不要强行打开任何可选值。

这里你正在做的是第一次while l1.next != nil它很好。您可以获取下一个对象,但是您要为其分配新值的第二个l1.next!.next! = ListNode(3) next仍为零,因此您的应用会出错。

希望它对你有所帮助

答案 1 :(得分:0)

根据Apple's documentation

  

可选链接是查询和调用属性的过程,   方法,以及当前可能为nil的可选项的下标。如果   optional包含值,属性,方法或下标调用   成功;如果optional是nil,属性,方法或下标   呼叫返回零。多个查询可以链接在一起,并且   如果链中的任何链接为零,则整个链优雅地失败。

您可以按照以下更新代码

// Definition for singly-linked list.
public class ListNode {
    public var val: Int
    public var next: ListNode?
    public init(_ val: Int) {
        self.val = val
        self.next = nil
    }
}

var l1 = ListNode(2)
l1.next  = ListNode(4)
l1.next?.next = ListNode(3) 
//By using the '?' operator, you're essentially saying that if l1's next is nil,
//do nothing; otherwise, assign ListNode(3) to it

对于你的第二个问题,这里的警告即将出现,因为你正在检查l1(非可选)对nil,这在你的情况下总会返回true。你想要某种递归。请尝试以下

func printValuesFrom(_ node: ListNode) {
    print(node.val)
    if let next = node.next {
        printValuesFromNode(next)
    }
}

printValuesFrom(l1)

答案 2 :(得分:0)

试试这种方式......

 public class ListNode {
        public var val: Int
        public var next: ListNode?
        public init(_ val: Int, _ next: ListNode?) {
            self.val = val
            self.next = next
        }
    }

    var l1 = ListNode(1,nil)

    var l2 = ListNode(2,nil)
    l1.next  = l2 

  // or l1.next = ListNode(2,nil)