Can you specify the return type in Swift as any collection of a certain type?

I implemented a user queue object that I would like to use to store previous items in the controller. I would like to use this type as a private variable in my controller and only expose it outside as just a CollectionType-compliant object so that clients can iterate or index the object without knowing any class-specific details such as a function clear().

Swift protocols cannot be shared, so unfortunately, I cannot just determine the getter to return CollectionOf<Type>. I implemented this behavior using the following abstract base class and subclassing my collection from it, but I was hoping there might be a faster and more built-in method for this, which I hope will also not require subclasses:

class AnyCollectionOf<MemberT, IndexT: ForwardIndexType>: CollectionType {
    // Sequence Type
    func generate() -> GeneratorOf<MemberT> {
        fatalError("must override")
    }

    // Collection Type
    typealias Index = IndexT
    typealias Element = MemberT

    subscript (index: Index) -> Element {
        get {
            fatalError("must override")
        }
    }

    var startIndex: Index {
        get {
            fatalError("must override")
        }
    }

    var endIndex: Index {
        get {
            fatalError("must override")
        }
    }
}
+5
source share
3 answers

The answer to your question heading, unfortunately, is no: there is no way for the jury-rig type CollectionType to be a stand-alone type that can be used as a variable or return type.

, SequenceType CollectionType, , , typealiases , , . , . , . ( , , - " ".)

,

func countItems(collection: CollectionType) -> Int { ... }

func countItems<T: CollectionType>(collection: T) -> Int { ... }

, (T), CollectionType.

, , , , , , . , CollectionType:

struct ShieldedCollection<UCT: CollectionType> : CollectionType
{
    private var underlying: UCT

    func generate() -> UCT.Generator { return underlying.generate() }
    subscript(index: UCT.Index) -> UCT.Generator.Element { return underlying[index] }
    var startIndex: UCT.Index { return underlying.startIndex }
    var endIndex: UCT.Index { return underlying.endIndex }
}

var foo = [1, 2, 3]
var shieldedFoo = ShieldedCollection(underlying: foo)

( UCT = " ".)

ShieldedCollection - , CollectionType, , .

, , , , API. Foo

ShieldedCollection<Array<Int>>

, - API, . , , , ShieldedCollection , , - Items() CollectionType, .

, , UCT ShieldedCollection:

struct ShieldedCollection<T> : CollectionType    // Changed!
{
    typealias UCT = [T]                          // Added!

    private var underlying: UCT                  // Everything else identical

    func generate() -> UCT.Generator { return underlying.generate() }
    subscript(index: UCT.Index) -> UCT.Generator.Element { return underlying[index] }
    var startIndex: UCT.Index { return underlying.startIndex }
    var endIndex: UCT.Index { return underlying.endIndex }
}

var foo = [1, 2, 3]
var shieldedFoo = ShieldedCollection(underlying: foo)

, - ShieldedCollection CollectionTypes, . (, typealias UCT.)

+2

, , 2 1 , :

open var labels: [UILabel] {
        return views.filter({ $0 is UILabel }).flatMap({ $0 }) as! [UILabel]
    }

: filter, flatMap (compactMap Swift 4) downforced

0

Swift 5.1, some:

func upNext() -> some Collection { ... }
0

All Articles