[英]Swift generic function calling function with return type overload
只是一個簡單的問題。 我有以下代碼,工作得很好:
class obA: Printable {
var description: String { get { return "obA" } }
}
class obB: Printable {
var description: String { get { return "obB" } }
}
func giveObject() -> obA { return obA() }
func giveObject() -> obB { return obB() }
var a: obA = giveObject()
var b: obB = giveObject()
println(a)
println(b)
正在調用giveObject的正確變體,一切都很好。 當然這只是一個簡化的案例,實際上在我的項目中有幾十個'giveObject'的重載,所有的返回類型都不同。 現在,我想制作一個通用函數來解析所有這些東西。 那么,下一步:
func giveGeneric<T>() -> T {
return giveObject()
}
var c: obA = giveGeneric()
println(c)
這抱怨了對giveObject的模糊使用。 我可以理解錯誤的來源,但我不知道如何解決它並使用這樣的結構......
即使您為任何可能的類型實現了giveObject
函數,這也無法工作。 由於T
可以是任何類型,因此giveGeneric
方法無法確定要調用的正確重載。
我能想到的唯一方法就是創建一個巨大的swift,其中包含你想要處理的類型數量的大小:
func giveGeneric<T>() -> T? {
switch "\(T.self)" {
case "\(obA.self)":
return giveObject() as obA as? T
case "\(obB.self)":
return giveObject() as obB as? T
default:
return .None
}
}
但我不認為即使拿着槍指向我的頭部也會使用這樣的解決方案 - 這真的很難看。
如果在所有情況下使用無參數構造函數創建實例,則可以創建協議並約束T
泛型類型以實現它:
protocol Instantiable {
init()
}
func giveGeneric<T: Instantiable>() -> T {
return T()
}
您可以使用內置以及新類型 - 例如:
extension String : Instantiable {
// `String` already implements `init()`, so nothing to add here
}
let s: String = giveGeneric()
或者,如果您願意,可以使協議聲明一個靜態的giveObject
方法而不是一個無參數的構造函數:
protocol Instantiable {
static func giveObject() -> Self
}
func giveGeneric<T: Instantiable>() -> T {
return T.giveObject()
}
extension String : Instantiable {
static func giveObject() -> String {
return String()
}
}
let s: String = giveGeneric()
首先只是一個注釋。
如果giveGeneric
的泛型類型只是T
,那么它可以是任何東西(String,Int,...)。 那么在這種情況下, giveObject()
應如何反應?
我的意思是,如果你寫:
let word : String = giveGeneric()
在內部你的泛型函數調用如下:
let result : String = giveObject() // Ambiguous use of giveObject
我宣布了一個協議如下:
protocol MyObject {
init()
}
然后我讓你的2個類符合協議
class obA: Printable, MyObject {
var description: String { get { return "obA" } }
required init() {}
}
class obB: Printable, MyObject {
var description: String { get { return "obB" } }
required init() {}
}
最后我可以寫這個
func giveGeneric<T:MyObject>() -> T {
return T()
}
現在我可以使用它:
let a1 : obA = giveGeneric()
let b1 : obB = giveGeneric()
您決定這是您正在尋找的解決方案還是僅僅是一種解決方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.