设置模板参数默认值



我写了这个类:

class Queue<T> {
var value: T
var next: Queue<T>?
init(_ items: Any...)
{ 
self.value = items[0]
}

但是我想知道有没有办法通过为参数"value"设置一些默认值来实现构造函数。我知道如果我把它贴花为" var value: T?" 没问题,但是是否有任何"黑客"解决方案与构造函数中的当前代码设置一些默认值,它是什么并不重要,因为我想制作这样的对象:var obj = Queue((,导致当前 Queue(( 崩溃

如果您确定将设置值并且不想处理 Optionals,则可以使用!来声明隐式解包的 Optional

class Queue<T> {
var value: T!
// ...
}

这里有更多关于这方面的 docs.swift.org

您在这里犯的设计错误是您将链表中的节点公开为公共 API。您的Queue<T>类对节点进行建模,当然,链接列表节点必须包含一个值。否则,它不是列表的真正节点,是吗?

相反,您应该有一个父LinkedList(或Queue,在您的例子中(结构,它封装了对头/尾LinkedListNode的引用。这样,可以使用LinkedList.headnil值对空列表进行建模。

以下是我将如何做到这一点:

struct LinkedList<T> {
class Node {
let value: T
let next: Node?
init(value: T, next: Node?) {
self.value = value
self.next = next
}
convenience init?(head: T?, tail: ArraySlice<T>) {
guard let head = head else { return nil }
self.init(
value: head,
next: Node(head: tail.first, tail: tail.dropFirst())
)
}
}
var head: Node?
init(_ elements: T...) {
self.init(elements)
}
// ugh, you can't forward a vararg in Swift, so you need to have this overload >_>
init(_ elements: [T]) {
self.head = Node(head: elements.first, tail: elements.dropFirst())
}
}
extension LinkedList: CustomStringConvertible {
var description: String {
guard let head = self.head else { return "LinkedList[empty]"}
let allNodes = sequence(first: head, next: { $0.next })
let body = allNodes
.map { String(describing: $0.value) }
.joined(separator: ", ")
return "LinkedList[(body)]"
}
}
print(LinkedList(1, 2, 3)) // => LinkedList[1, 2, 3]

然后我会将Queue<T>实现为一个围绕LinkedList<T>的基本包装器

struct Queue<T> {
var list: LinkedList<T>
init(_ initialElements: T...) {
self.list = LinkedList(initialElements)
}
mutating func push(_ newElement: T) {
let newHead = LinkedList.Node(value: newElement, next: self.list.head)
self.list.head = newHead
}
mutating func pop() -> T? {
guard let head = self.list.head else { return nil }
self.list.head = head.next
return head.value
}
}
var q = Queue(3, 2, 1)
print(q) // => Queue<Int>(list: LinkedList[3, 2, 1])
q.push(4); print(q) // => Queue<Int>(list: LinkedList[4, 3, 2, 1])
q.push(5); print(q) // => Queue<Int>(list: LinkedList[5, 4, 3, 2, 1])
print(q.pop(), q) // => Optional(5) Queue<Int>(list: LinkedList[4, 3, 2, 1])
print(q.pop(), q) // => Optional(4) Queue<Int>(list: LinkedList[3, 2, 1])
print(q.pop(), q) // => Optional(3) Queue<Int>(list: LinkedList[2, 1])
print(q.pop(), q) // => Optional(2) Queue<Int>(list: LinkedList[1])
print(q.pop(), q) // => Optional(1) Queue<Int>(list: LinkedList[empty])
print(q.pop(), q) // => nil Queue<Int>(list: LinkedList[empty])

最新更新