首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用泛型类声明泛型类为参数。

使用泛型类声明泛型类为参数。
EN

Stack Overflow用户
提问于 2019-07-19 18:24:57
回答 2查看 110关注 0票数 1

我编写了这些简单的泛型类,它运行得很好:

代码语言:javascript
复制
class LinkedListNode <T> {
    var value: T
    var next: LinkedListNode<T>?
    weak var prev: LinkedListNode<T>?
    init(value: T) {
        self.value = value
        self.next = nil
    }
}

class LinkedList<T> {
    var first: LinkedListNode<T>? = nil
    var last: LinkedListNode<T>? = nil
    var count = 0
    @discardableResult func append(_ value: T) -> LinkedListNode<T> {
        let new = LinkedListNode(value: value)
        new.prev = last
        last?.next = new
        count += 1
        last = new
        if first == nil {
            first = new
        }
        return new
    }
}

我用它就像:

代码语言:javascript
复制
let list = LinkedList<Int>()
list.append(3)
let lastNode = list.append(5)

现在我意识到,在某些情况下,我需要定制一个节点:CustomNode<T>LinkedListNode<T>的子类。因此,我希望能够将要用作节点的类传递为:

代码语言:javascript
复制
let list = LinkedList<CustomNode<Int>>()
list.append(3)
let customNode = list.append(5)

我怎么能宣布我的班级有这样的或类似的东西?

我尝试了下面的声明,但是奇怪的错误出现了。这有可能吗?

代码语言:javascript
复制
class LinkedList<Node<T>: LinkedListNode<T>> { ... 

更新2019/07/26。

即使使用Kamran的方法,该方法也不会编译。如果没有协议,我不确定这是否可行。请看我对Kamran的回答的评论。

代码语言:javascript
复制
func remove(node: LinkedListNode<T>) { // change to `func remove(node: U)`
    node.next?.prev = node.prev
    node.prev?.next = node.next
    if node === first {
        first = first?.next
    }
    if node === last {
        last = last?.prev // Error here: "Cannot assign value of LinkedListNode<T>? to U?"
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-19 19:24:01

您正在尝试的语法如下所示,

代码语言:javascript
复制
class LinkedListNode <T> {
    var value: T
    var next: LinkedListNode<T>?
    weak var prev: LinkedListNode<T>?
    required init(value: T) {
        self.value = value
        self.next = nil
    }
}

class GenericCustomNode<T>: LinkedListNode<T> {

    required init(value: T) {
        super.init(value: value)
    }
}

class NonGenericCustomNode: LinkedListNode<Int> {

    required init(value: Int) {
        super.init(value: value)
    }
}

class LinkedList<T, U: LinkedListNode<T>> {
    var first: U? = nil
    var last: U? = nil
    var count = 0
    @discardableResult func append(_ value: T) -> U {
        let new = U(value: value)
        new.prev = last
        last?.next = new
        count += 1
        last = new
        if first == nil {
            first = new
        }
        return new
    }

    func remove(node: U) {
        node.next?.prev = node.prev
        node.prev?.next = node.next
        if node === first {
            first = first?.next as? U
        }
        if node === last {
            last = last?.prev as? U
        }
    }
}

使用:

代码语言:javascript
复制
let list = LinkedList<Int, LinkedListNode<Int>>()
list.append(5)
print(list.first?.value)

let someCustom = LinkedList<Int, GenericCustomNode<Int>>()
someCustom.append(15)

print(someCustom.first?.value)

let otherCustom = LinkedList<Int, NonGenericCustomNode>()
otherCustom.append(2)
print(otherCustom.first?.value)

输出:

代码语言:javascript
复制
 Optional(5) 
 Optional(15) 
 Optional(2)
票数 1
EN

Stack Overflow用户

发布于 2019-07-19 18:44:56

您需要用一个协议定义一个关联类型

代码语言:javascript
复制
protocol Node: class {
    associatedtype Value
    var value: Value {get set}
    var next: Self? {get set}
    var prev: Self? {get set}

    init(value: Value)
}

final class BasicNode<Value>: Node {
    var value: Value
    var next: BasicNode<Value>?
    weak var prev: BasicNode<Value>?

    init(value: Value) {
        self.value = value
    }
}

final class CustomNode<Value>: Node {
    // customize however you want
    var value: Value
    var next: BasicNode<Value>?
    weak var prev: BasicNode<Value>?

    init(value: Value) {
        self.value = value
    }
}

class LinkedList<N: Node> {
    var first: N? = nil
    var last: N? = nil
    var count = 0

    @discardableResult
    func append(_ value: N.Value) -> N {
        let new = N(value: value)
        new.prev = last
        last?.next = new
        count += 1
        last = new
        if first == nil {
            first = new
        }
        return new
    }
}

但是,这需要始终以一种恼人的方式使用基本链接列表:

代码语言:javascript
复制
let list = LinkedList<BasicNode<Int>>()

根据您需要自定义节点的方式,我将考虑找到一种使用依赖注入自定义依赖注入类本身中的行为的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57117876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档