我正在练习 Swift 语言。我正在用 xcode 中的游乐场解决 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.下一页!.下一个!= ListNode(3( 或 l1.next.next!= 列表节点(3(
我以为我可以解开包装,因为我确信我为第二个节点放置了正确的节点。
我也试过这个
var l1 = ListNode(2)
l1.next? = ListNode(4)
l1.next!.next? = ListNode(3)
那么我会得到
执行中断,原因:EXC_BAD_INSTRUCTION (代码=EXC_I386_INVOP,子代码=0x0(。
请让我理解可选表达式的正确用法。
你在这里得到错误
//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
两次而不解开它。
l1.next?.next = ListNode(3)
对于第二种情况
while l1 != nil{
print(l1.val)
if let nextNode = l1.next{
l1 = nextNode
}
}
编辑2
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
很好。 您可以获取下一个对象,但对于分配新值的第二个next
ListNode(3)
仍然是零,所以你的应用程序抛出错误。
希望对您有所帮助
根据Apple的文档,
可选链接是查询和调用属性的过程, 方法,以及当前可能为 nil 的可选选项上的下标。如果 可选包含值、属性、方法或下标调用 成功;如果可选为 nil,则为属性、方法或下标 调用返回 nil。可以将多个查询链接在一起,并且 如果链中的任何链接为 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)
试试这个方式...
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)