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?

但这现在与您的问题无关。