Swift: 如何比较 "if" 子句中的 Optional
Swift: How to compare Optional in "if" clause
我正在练习 Swift 用数组构建树。
我有一个 class 节点。每个节点都有一个 ID 和一个 parent ID。如果节点是 top-level 节点,parent ID 可以为 nil。所以我将 parent ID 设置为可选。
然后我手动(出于测试目的)创建了一个节点数组,其中包含多棵树。所以有多个节点 parent ID = nil.
然后我创建了一个通过 parent ID 查找节点的函数。
编译器没有抱怨。但是,当 iPhone 模拟器中的 运行 时(我试图在表视图中显示节点),一条消息显示 在函数 :[=14 的 if 子句中=]
fatal error: unexpectedly found nil while unwrapping an Optional value
请帮忙。谢谢
这是代码。
(为了我自己的习惯,我在每一行的末尾写上“;”。)
class Node {
var id:Int;
var parent:Int!;
init(id:Int, parent:Int!) {
self.id = id;
self.parent = parent;
}
}
var allNodes = [
Node(id:1, parent: nil),
Node(id:2, parent: nil),
Node(id:3, parent: 1),
Node(id:4, parent: 1),
Node(id:5, parent: 2),
Node(id:6, parent: 2),
Node(id:7, parent: 2)
];
func findNodes(parent:Int!) -> [Node] {
var arr:[Node] = [];
for node in allNodes {
if node.parent == parent! {
// if I use "if node.parent == parent" without the "!" it gives me the same error
arr.append(node);
}
}
return arr;
}
let nodes = self.findNodes(nil);
// called in tableview functions.
// same message if I use findNodes(1).
您的查找函数声明为
func findNodes(parent:Int!) -> [Node]
其中参数被声明为隐式展开的可选参数,
所以它会在每次访问时解包。如果你想通过nil
作为参数,那么 "normal" 可选更有意义:
func findNodes(parent:Int?) -> [Node] {
var arr:[Node] = [];
for node in allNodes {
if node.parent == parent {
arr.append(node);
}
}
return arr;
}
请注意,您可以将代码简化为 (Swift 1.2):
func findNodes(parent:Int?) -> [Node] {
return filter(allNodes) { [=12=].parent == parent };
}
声明 parent
属性 也更有意义
在 Node
class 中作为可选,如果 nil
是一个 "expected" 值:
class Node {
var id : Int;
var parent : Int?;
init(id:Int, parent : Int?) {
self.id = id;
self.parent = parent;
}
}
或者可能是(可选的)指向父节点的指针:
var parent : Node?
但这现在与您的问题无关。
我正在练习 Swift 用数组构建树。
我有一个 class 节点。每个节点都有一个 ID 和一个 parent ID。如果节点是 top-level 节点,parent ID 可以为 nil。所以我将 parent ID 设置为可选。
然后我手动(出于测试目的)创建了一个节点数组,其中包含多棵树。所以有多个节点 parent ID = nil.
然后我创建了一个通过 parent ID 查找节点的函数。
编译器没有抱怨。但是,当 iPhone 模拟器中的 运行 时(我试图在表视图中显示节点),一条消息显示 在函数 :[=14 的 if 子句中=]
fatal error: unexpectedly found nil while unwrapping an Optional value
请帮忙。谢谢
这是代码。 (为了我自己的习惯,我在每一行的末尾写上“;”。)
class Node {
var id:Int;
var parent:Int!;
init(id:Int, parent:Int!) {
self.id = id;
self.parent = parent;
}
}
var allNodes = [
Node(id:1, parent: nil),
Node(id:2, parent: nil),
Node(id:3, parent: 1),
Node(id:4, parent: 1),
Node(id:5, parent: 2),
Node(id:6, parent: 2),
Node(id:7, parent: 2)
];
func findNodes(parent:Int!) -> [Node] {
var arr:[Node] = [];
for node in allNodes {
if node.parent == parent! {
// if I use "if node.parent == parent" without the "!" it gives me the same error
arr.append(node);
}
}
return arr;
}
let nodes = self.findNodes(nil);
// called in tableview functions.
// same message if I use findNodes(1).
您的查找函数声明为
func findNodes(parent:Int!) -> [Node]
其中参数被声明为隐式展开的可选参数,
所以它会在每次访问时解包。如果你想通过nil
作为参数,那么 "normal" 可选更有意义:
func findNodes(parent:Int?) -> [Node] {
var arr:[Node] = [];
for node in allNodes {
if node.parent == parent {
arr.append(node);
}
}
return arr;
}
请注意,您可以将代码简化为 (Swift 1.2):
func findNodes(parent:Int?) -> [Node] {
return filter(allNodes) { [=12=].parent == parent };
}
声明 parent
属性 也更有意义
在 Node
class 中作为可选,如果 nil
是一个 "expected" 值:
class Node {
var id : Int;
var parent : Int?;
init(id:Int, parent : Int?) {
self.id = id;
self.parent = parent;
}
}
或者可能是(可选的)指向父节点的指针:
var parent : Node?
但这现在与您的问题无关。