值类型混淆
Value type confusion
我在 Whosebug 上的第一个问题 :)
我几天前开始学习 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,generic。保持简单!
这是我在 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()
returns 一个值为 0 的 Node
,则无法知道那是否是因为子列表为空,或者是否真的存在 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: { [=11=].value < .value })
}
}
Swift 相当于过时的 Java 方法
这里是 Swift 对 bestChild
方法的过时 Java 方法的实现。这只是为了比较。 不要这样做!
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 解决方案中使用数组?
我在 Whosebug 上的第一个问题 :)
我几天前开始学习 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,generic。保持简单! 这是我在 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()
returns 一个值为 0 的Node
,则无法知道那是否是因为子列表为空,或者是否真的存在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: { [=11=].value < .value })
}
}
Swift 相当于过时的 Java 方法
这里是 Swift 对 bestChild
方法的过时 Java 方法的实现。这只是为了比较。 不要这样做!
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 解决方案中使用数组?