我在 StackOverflow 上的第一个问题:)
几天前我开始在 XCode 中学习 Swift,但在理解 Swift 中的值类型时遇到了一些困难。由于我对Java非常熟悉,所以我将用Java解释我的问题。这是我想用 Swift 编写的内容。
class Node {
public int value;
public List<Integer> children;
public Node parent;
public Node() {
value = 0;
children = new ArrayList<Integer>();
}
public Node bestChild() {
Node result = new Node();
for (child : this.children) {
if (child.value > result.value)
result = child;
}
return result;
}
}
为了这个问题,我们在这里不讨论私有(private)、公共(public)或通用。保持简单即可! 这是我在 Swift 中的尝试。
public class Node {
var value: Int
var children: NSSet
var parent: Node?
public init() {
self.value = 0
children = NSSet()
}
public func bestChild() -> Node {
var result = Node()
for child in children {
if (child.value > result.value) { //error
result = child //error
}
}
return result
}
}
if语句的条件和里面的行都有错误。 XCode 建议强制转换变量,但仍然没有解决错误。
if ((child as AnyObject).value > result.value) {
result = child as! Node
}
由于 Java 是我唯一知道的语言,如果有人能用 Java 来解释它,我将不胜感激。如果没有,请保持简单,以便我可以理解它:)
提前致谢!
最佳答案
欢迎来到 Stack Overflow 和 Swift 编程!
Java 代码的改进
首先,我建议对 Java 代码进行一些更改。
- 尽可能使用静态初始化器。完成此操作后,您甚至不需要显式构造函数。
- 您的
children
变量的类型为List<Integer>
,但我怀疑你的意思是List<Node>
. - 不要创建新的
Node
只是为了比较。通过这种方法,如果bestChild()
返回Node
值为 0 时,无法知道这是否是因为子列表为空,或者是否确实存在Node
值为 0 时为最高值。我会使用流 API,尽管您可以手动实现此类功能。
最终结果如下:
class Node {
public int value;
public List<Node> children = new ArrayList<>();
public Node parent; // Unused?
public Node bestChild() {
// Modern, easy approach:
return children
.stream()
.max((x, y) -> Integer.compare(x.value, y.value))
.get();
// Old, classic Java approach:
/*
int max = Integer.MIN_VALUE;
Node maxNode = null;
for (Node child : this.children) {
if (max < child.value) {
max = child.value;
maxNode = child;
}
}
return maxNode; */
}
}
Swift 等效
这是我用 Swift 编写的方法。欢迎提出后续问题
class Node {
let value = 0
let children = [Node]()
weak var parent: Node? // Unused?
func bestChild() -> Node? {
return children.max(by: { $0.value < $1.value })
}
}
过时的 Java 方法的 Swift 等效项
这是对 bestChild
过时的 Java 方法的 Swift 实现方法。这只是为了比较。 不要这样做!
func bestChild() -> Node? {
var max = Int.min
var maxNode: Node?
for child in children {
if max < child.value {
max = child.value
maxNode = child
}
}
return maxNode
}
要解决解决方案尝试中的问题:
NSSet
是Swift
,如HashSet
(没有泛型类型参数,不是 HashSet<T>
)是针对 Java 的。它是 Foundation
中的数据类型库,是为 Objective-C 发明的。在 99.999% 的情况下,你不应该在 Swift 中使用它。 NSSet
充当一组 AnyObject
。为了能够调用.value
对于集合中的一个对象,您需要首先手动将该对象转换为 Node
.
解决所有问题的方法是使用 Set<Int>
,这是 Swift 的原生 Set
数据结构。虽然这提出了一个问题,为什么在 swift 解决方案中使用 Set,而在 Java 解决方案中使用数组?
关于java - 值类型困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364830/