代码之家  ›  专栏  ›  技术社区  ›  Chris Wood

AssociatedType受限于集合的Swift协议扩展,不能使用下标

  •  3
  • Chris Wood  · 技术社区  · 7 年前

    protocol DDCDataSource: Collection
    {
        associatedtype Object
        var object: Object {get set}
    }
    

    无法为“Self”类型的值下标。对象“”的索引类型为“Self”。对象索引'

    enter image description here

    extension DDCDataSource where Object: Collection
    {
        typealias Index = Object.Index
    
        var startIndex: Object.Index {
            get {
                return object.startIndex
            }
        }
    
        var endIndex: Object.Index {
            get {
                return object.endIndex
            }
        }
    
        subscript(position: Object.Index) -> Element
        {
            return object[position]
        }
    
        func index(after i: Object.Index) -> Object.Index {
            return object.index(after: i)
        }
    }
    
    3 回复  |  直到 7 年前
        1
  •  6
  •   Martin R    7 年前

    简短回答: Object.Element

    subscript(position: Object.Index) -> Object.Element {
        return object[position]
    }
    

    Index

    typealias Element = Object.Element
    
    subscript(position: Object.Index) -> Element {
        return object[position]
    }
    

    这使代码按预期编译和运行。


    说明: 这个 subscript method Collection 声明为

    subscript(position: Self.Index) -> Self.Element { get }
    

    哪里 Self.Index Self.Element 收藏。使用您的代码

    subscript(position: Object.Index) -> Element {
        return object[position]
    }
    

    编译器推断 自己指数 Object.Index 两者之间没有关系 对象要素 (即 object[position] ). 错误变得更加明显 如果添加显式转换:

    subscript(position: Object.Index) -> Element {
        return object[position] as Element
    }
    

    现在编译器抱怨

    正确的解决方案是 知道吗 对象要素

    下标(位置:Object.Index)->对象元素{
    返回对象[位置]
    

    因此编译器 推断 DDCDataSource.Element 成为 对象要素


    完整的自包含示例: (Swift 4,Xcode 9 beta 6)

    (请注意,您可以省略 get 属性。)

    protocol DDCDataSource: Collection {
        associatedtype Object
        var object: Object { get set }
    }
    
    extension DDCDataSource where Object: Collection {
        var startIndex: Object.Index {
            return object.startIndex
        }
    
        var endIndex: Object.Index {
            return object.endIndex
        }
    
        subscript(position: Object.Index) -> Object.Element {
            return object[position]
        }
    
        func index(after i: Object.Index) -> Object.Index {
            return object.index(after: i)
        }
    }
    
    struct MyDataSource: DDCDataSource {
        var object = [1, 2, 3]
    }
    
    let mds = MyDataSource()
    print(mds[1]) // 2
    
    for x in mds { print(x) } // 1 2 3
    
        2
  •  0
  •   dengApro    7 年前

    首先,我认为你应该定义 Element

    其次,你使用 object[position] ,对象符合集合,但不属于集合类型。显然它不是数组。

    apple says 符合CustomDebugStringConvertible/CustomReflectable/ CustomStringConvertible/CVarArg/Decodable/Encodable/

    我想 extension DDCDataSource where Object: Array

    阵列中的元素应为 要素 定义只是小费。

        3
  •  0
  •   Torongo    7 年前

    试试这个:

    subscript(position:Object.Index) -> Element
        {
            var element: Element
            guard let elementObject = object[position] else {
                //handle the case of 'object' being 'nil' and exit the current scope
            }
            element = elementObject as! Element
    
        }