Generics Swift-Can';t将BST节点转换为通用节点

Generics Swift-Can';t将BST节点转换为通用节点,generics,swift,Generics,Swift,当为具体类型实现时,我的二叉搜索树节点在游乐场中运行良好: class Node { var data: Int var leftChild: Node? var rightChild: Node? init(data: Int){ self.data = data } } let n = Node(data: 42) // {data 42 nil nil} 当我试图使其通用时,Xcode崩溃并烧毁: class Gene

当为具体类型实现时,我的二叉搜索树节点在游乐场中运行良好:

class Node {
    var data: Int
    var leftChild: Node?
    var rightChild: Node?

    init(data: Int){
        self.data = data
    }
}

let n = Node(data: 42)      // {data 42 nil nil}
当我试图使其通用时,Xcode崩溃并烧毁:

class GenericNode<T: Comparable> {
    var data: T
    var leftChild: GenericNode?
    var rightChild: GenericNode?

    init(data: T){
        self.data = data
    }
}

let g = GenericNode<Int>(data: 42)
类GenericNode{
var数据:T
var leftChild:GenericNode?
var rightChild:GenericNode?
初始化(数据:T){
self.data=数据
}
}
设g=GenericNode(数据:42)

当逐行输入时,Xcode将一直存在,直到我在
init
中输入实际分配为止。我试图指定
,但显然不允许向
任何对象添加约束。如何在Swift中创建适当约束的通用容器?

我认为这更可能是一个bug。如果您尝试在
Swift
终端中执行此操作,它将抛出一个错误:

LVM错误:未实现IRGen功能!非固定类布局

一种解决方法是让
T
符合
NSObject

因为
NSObject
是一个协议,它需要像这样的方法,我认为这相当于
Comparable
的实现,现在是

因此,代码如下所示:

class GenericNode<T: NSObject> {
    var data: T
    var leftChild: GenericNode?
    var rightChild: GenericNode?

    init(data: T){
        self.data = data
    }
}

let g = GenericNode<NSNumber>(data: 42)

如果您只是尝试编写基本的BST内容,这应该足够好了。

这里肯定有一些bug。此代码不会崩溃:

class GenericRootClass {
}

class GenericNode<T: GenericRootClass where T : Comparable> {

    let data: T
    var leftChild: GenericNode<T>?
    var rightChild: GenericNode<T>?

    init(data: T) {
        self.data = data
    }
}

能够使Xcode 6 beta 2崩溃。泛型类目前似乎不起作用。

相关:这在Xcode 6.1中似乎是固定的。这将允许我创建
g
,但不允许创建另一个
节点
g2
,并检查类似
g.data
。您提出的解决方案缺少
可比
协议,在我看来,该协议对于构建BST至关重要。@pjs否,因为
T
符合
NSObject
T
必须实现
isEqual
方法。然后,假设您有另一个
let f=GenericNode(数据:42)
,它们可以通过
g.data.isEqual(f.data)
进行比较。检查两个对象是否相等不足以构建二元搜索树。如果它们不相等,你真的需要知道哪个大,哪个小。@pjs啊哈!很抱歉但是它有
isGreaterThan()
islesshan()
方法。我真的希望有一个“全速”的解决方案。也许在未来一代的编译器中。同时,使用
is…Than()
方法检查
NSNumber
NSString
这两种方法,因此感谢您提供了一个解决方法。非常好地了解了子节点
的声明,谢谢。从长远来看,我打算使
数据
不可变,但从短期来看,我希望能够在操场上玩单个
节点
s。不过,我看不出
GenericRootClass
如何帮助解决基本问题。Swift类,如
Int
String
不是它的子类,我希望
节点
能够存储实现
可比
的任何有效负载(包括我尚未创建的类中的对象)。抱歉,不,它不能解决问题。这只是我在测试中得出的结论,看看“将崩溃的事物”的范围是什么;这是将类型参数约束到特定类层次结构(任何类层次结构)的证据。我建议用NSObject来代替它(同时保留可比性约束),但至少对于NSNumber来说,苹果与可可类型之间的桥梁并没有延伸到在它们应该具有可比性时将它们标记为可比。你自己添加这个扩展就足够简单了,但你不必做任何事情。这很令人难过——我看到了语言的巨大潜力,但现在很多应该简单的事情占用了太多的时间。因为没有人提出一个快速的解决方案,我将你的答案标记为解决方案。
class GenericRootClass {
}

class GenericNode<T: GenericRootClass where T : Comparable> {

    let data: T
    var leftChild: GenericNode<T>?
    var rightChild: GenericNode<T>?

    init(data: T) {
        self.data = data
    }
}
class GenericRootClass<T> {
    var data: T?
}