2016-03-05 90 views
4

如何創建泛型數組?例如:快速數組泛型

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] 

如何聲明泛型任何類型(如Thing<?>Thing<Any>東西)的?

+0

不幸的是,仿製藥尚未使用這種模式。 – PeejWeej

回答

3

你可以這樣做:
let things: [Any] = [intThing, stringThing]

Thing不是它自己的有效的類型。 Thing<String>是一種類型,而Thing<Int>是另一種類型,您不能在數組中混用不同的類型。

你有沒有注意到,即使let things: [Thing]無法編譯?

我認爲,你可能嘗試做會與相關的值枚舉更好的服務器。


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] 

nice article about advance enum trick here
在這種file約包裝的plist數據到一個單一的結構中,存在使用了的EntityType枚舉的。


你可以向任何一個枚舉值相關聯,但它必須是一個完全合格的類型。所以你不能使用MyStruct,因爲它不是完全合格的,你需要使用MyStruct<Int>來完全符合條件。這意味着您需要爲每個想要與MyStruct一起使用的通用類型創建一個案例。

也就是說只要你可以用通用的方法去。
我不確定你想要做什麼。但是,如果你想達到某種多態性的依賴上T操作,但不要使用T作爲輸入輸出也不應該讓你的Thing實現協議,使該協議的一個數組,並打電話給你的多態方法上的方法協議。

+0

謝謝,這樣一個枚舉看起來像什麼? –

+0

我的'Thing'結構實際上有一些屬性,據我所知,它不適用於枚舉。 –

+0

@SteveKuo,我已經更新了代碼,以便您可以看到它如何與泛型一起工作,但是您將需要每種'T'的情況。 –

0

您可以使用一個enum

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

現在,您可以創建一個包含字符串或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