我正在练习斯威夫特语言。 我在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)。
请让我理解正确使用可选表达式。
答案 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)
可选链接是查询和调用属性的过程, 方法,以及当前可能为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)