Swift generic array

How to create an array of generics? Example:

struct Thing<Any> {
}

let intThing = Thing<Int>()
let stringThing = Thing<String>()

// This line doesn't compile
// Cannot convert value of type 'Thing<Int>' to expected type 'Thing'
let things: [Thing] = [intThing, stringThing]

How to declare a generic type of any type (something like Thing<?>or Thing<Any>)?

+4
source share
4 answers

You can do it:
  let things: [Any] = [intThing, stringThing]

Thingnot a valid type. Thing<String>is a type, but Thing<Int>is a different type, and you cannot mix different types inside an array.

Did you notice that it does let things: [Thing]n't even compile?

I think what you are probably trying to do would be better than an enumerated server with related values.


struct MyStruct<T> {

    let property: T
    init(property: T) {
        self.property = property
    }
}

enum Thing {
    case int(Int)
    case string(String)
    case intStruct(MyStruct<Int>)
}

// creation
let myInt = Thing.int(2)
let myString = Thing.string("string")
let myIntStruct = Thing.intStruct(MyStruct<Int>(property: 3))

// down side is that you need a 'case' clause to retrieve the data
switch myIntStruct {
case let .int(value):
    print("have a int: \(value)")
case let .string(value):
    print("have a string: \(value)")
case let.intStruct(value):
    print("have a intStruct\(value)")
}

// An array of Thing
let things: [Thing] = [myInt, myString, myIntStruct]

enum trick here
Plist EntityType.


- , . MyStruct, , MyStruct<Int> . , , MyStruct.

.
, . , , T, T , Thing .

+3

enum Thing {
    case Text(String)
    case Integer(Int)
}

Thing, String Int

let thingWithText = Thing.Text("Hello world")
let thingWithInt = Thing.Integer(123)

Thing(s) ( ).

let things = [thingWithText, thingWithInt]

,

things.forEach { (thing) -> () in
    switch thing {
    case .Text(let text): print(text)
    case .Integer(let integer): print(integer)
    }
}
0

protocol Six {}
struct Thing<Any> :Six {}

let intThing = Thing<Int>()
let stringThing = Thing<String>()
let things: [Six] = [intThing, stringThing]
0

, , :

protocol ThingProtocol {
    func doSomething()

    // if you want to expose generic functions/properties
    // use functions/properties which have the most specific type
    // for Thing<T: AProtocol> it should be `var anyValue: AProtocol { get }`
    // here: `Any` since T in Thing<T> can be anything
    var anyValue: Any { get }
}

struct Thing<T>: ThingProtocol {
    var value: T

    // ThingProtocol implementation
    var anyValue: Any { return value as Any }
    func doSomething() { ... }
}

let intThing = Thing<Int>(value: 42)
let stringThing = Thing<String>(value: "101010")

let things: [ThingProtocol] = [intThing, stringThing]

things[0].doSomething()
things[0].anyValue // returns a value of type Any

// you cannot call `value` since it is not specified in the protocol. If you do it, it would result in an error in `Thing<T>`
things[0].value // error
0

All Articles