Generics Swift 3在通用链表实现上的序列协议扩展问题。
使用swift 3,通过XCode 8.2 beta版和swift build cli,我正试图编译一个游戏,演示我找到的链接列表的实现@ 报告的错误是:错误:无法将“Node”类型的值转换为预期的参数类型“Node” 该错误发生在迭代器扩展中。对makeIterator函数中构造函数的调用是错误行 返回LinkedListInterator(startNode:start) 我尝试了多种方法将startNode强制转换为可接受的类型,但都没有成功。我很想知道应该如何纠正这一点,同样重要的是,为什么它首先是一个错误。提前谢谢 有关守则:Generics Swift 3在通用链表实现上的序列协议扩展问题。,generics,swift3,xcode8,Generics,Swift3,Xcode8,使用swift 3,通过XCode 8.2 beta版和swift build cli,我正试图编译一个游戏,演示我找到的链接列表的实现@ 报告的错误是:错误:无法将“Node”类型的值转换为预期的参数类型“Node” 该错误发生在迭代器扩展中。对makeIterator函数中构造函数的调用是错误行 返回LinkedListInterator(startNode:start) 我尝试了多种方法将startNode强制转换为可接受的类型,但都没有成功。我很想知道应该如何纠正这一点,同样重要的是,为
/* Node */
public class Node<T: Equatable> {
typealias NodeType = Node<T>
/// The value contained in this node
public let value: T
var next: NodeType? = nil
var previous: NodeType? = nil
public init(value: T) {
self.value = value
}
}
/* Linked List */
public final class LinkedList<T: Equatable> {
public typealias NodeType = Node<T>
fileprivate var start: NodeType? {
didSet {
// Special case for a 1 element list
if end == nil {
end = start
}
}
}
fileprivate var end: NodeType? {
didSet {
// Special case for a 1 element list
if start == nil {
start = end
}
}
}
/// The number of elements in the list at any given time
public fileprivate(set) var count: Int = 0
/// Wether or not the list is empty. Returns `true` when
/// count is 0 and `false` otherwise
public var isEmpty: Bool {
get {
return count == 0
}
}
/// Create a new LinkedList
///
/// - returns: An empty LinkedList
public init() {
}
/// Create a new LinkedList with a sequence
///
/// - parameter: A sequence
/// - returns: A LinkedList containing the elements of the provided sequence
public init<S: Sequence>(_ elements: S) where S.Iterator.Element == T {
for element in elements {
append(value: element)
}
}
}
public struct LinkedListIterator<T: Equatable>: IteratorProtocol {
public typealias Element = Node<T>
/// The current node in the iteration
private var currentNode: Element?
private init(startNode: Element?) {
currentNode = startNode
}
public mutating func next() -> LinkedListIterator.Element? {
let node = currentNode
currentNode = currentNode?.next
return node
}
}
extension LinkedList: Sequence {
public typealias Iterator = LinkedListIterator<T>
public func makeIterator() -> LinkedList.Iterator {
return LinkedListIterator(startNode: start)
}
}
/*节点*/
公共类节点{
typealias节点类型=节点
///此节点中包含的值
公共出租价值:T
var next:NodeType?=nil
变量前一个:节点类型?=nil
公共初始化(值:T){
自我价值=价值
}
}
/*链表*/
公共最终类链接列表{
public-typealias-NodeType=节点
fileprivate变量开始:节点类型{
迪塞特{
//1元素列表的特殊情况
如果end==nil{
结束=开始
}
}
}
fileprivate变量结束:节点类型{
迪塞特{
//1元素列表的特殊情况
如果start==nil{
开始=结束
}
}
}
///在任何给定时间列表中的元素数
public fileprivate(set)变量计数:Int=0
///列表是否为空。当
///计数为0,否则为'false'
公共变量是空的:Bool{
得到{
返回计数==0
}
}
///创建一个新的LinkedList
///
///-返回:一个空的LinkedList
公共init(){
}
///使用序列创建新的LinkedList
///
///-参数:一个序列
///-返回:包含所提供序列元素的LinkedList
public init(u元素:S),其中S.Iterator.Element==T{
对于元素中的元素{
追加(值:元素)
}
}
}
公共结构LinkedListIterator:IteratorProtocol{
公共类型别名元素=节点
///迭代中的当前节点
私有变量currentNode:元素?
私有初始化(startNode:Element?){
currentNode=startNode
}
public mutating func next()->LinkedListIterator.Element{
让节点=当前节点
currentNode=currentNode?下一步
返回节点
}
}
扩展链接列表:序列{
公共类型别名迭代器=链接标识符迭代器
public func makeIterator()->LinkedList.Iterator{
返回LinkedListInterator(startNode:start)
}
}
这是一条完全误导性的错误消息(已作为bug提交,请参阅)–问题是您的LinkedListIterator
的init(startNode:)
初始化器标记为private
,因此无法从LinkedList
类中访问
一种选择是将其设置为fileprivate
:
fileprivate init(startNode: Element?) {
currentNode = startNode
}
这是一条完全误导性的错误消息(已作为bug提交,请参阅)–问题在于
LinkedList迭代器的init(startNode:)
初始化器标记为private
,因此无法从LinkedList
类中访问
一种选择是将其设置为fileprivate
:
fileprivate init(startNode: Element?) {
currentNode = startNode
}
非常感谢你,哈米什。事后看来,这似乎很明显,因为我已经在代码的其他地方将保护级别更改为fileprivate,但由于消息的性质而被取消。一旦有机会,我会尝试你建议的修复方法并报告。init方法的保护级别确实是问题所在。再次感谢哈米什!很高兴帮助@Chris:)非常感谢你,哈米什。事后看来,这似乎很明显,因为我已经在代码的其他地方将保护级别更改为fileprivate,但由于消息的性质而被取消。一旦有机会,我会尝试你建议的修复方法并报告。init方法的保护级别确实是问题所在。再次感谢哈米什!很高兴帮助@Chris:)