[英]Swift array of generics
如何創建泛型數組? 例:
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>
)?
你可以這樣做:
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]
關於提前枚舉技巧的好文章
在該文件有關包裝的plist數據到一個單一的結構中,存在使用了的EntityType枚舉的。
您可以將任何內容與枚舉值相關聯,但它必須是完全限定的類型。 因此,您不能使用MyStruct,因為它不完全合格,您需要使用MyStruct<Int>
來完全合格。 這意味着您需要為要與MyStruct一起使用的每個泛型類型創建一個案例。
這是您使用通用方法所能做到的。
我不確定您要做什么。 但是,如果要實現某種依賴於在T
上操作但不使用T
作為輸入或輸出的方法的多態,則應使Thing
實現一個協議並對該協議進行數組,然后在該協議上調用多態方法協議。
您可以使用一個枚舉
enum Thing {
case Text(String)
case Integer(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)
}
}
這會有所幫助
protocol Six {}
struct Thing<Any> :Six {}
let intThing = Thing<Int>()
let stringThing = Thing<String>()
let things: [Six] = [intThing, stringThing]
您可以使用包含所有要使用的相關屬性和功能的協議:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.