[英]Swift 3 generic function ambiguous return
我需要一個函數來解決類中的不同依賴關系。 但是出現了編譯錯誤。 是否可以創建該泛型函數,或者Swift中存在一些編譯器約束?
import Foundation
protocol Client: class {
var description: String { get }
}
final class ImportantPerson : Client {
var description: String {
return "Important person"
}
}
protocol Order: class {
var description: String { get }
}
final class LastOrder : Order {
var description: String {
return "Last order"
}
}
final class A {
fileprivate func resolveDependency<T>() -> T {
return resolve() as T
}
private func resolve() -> Client {
return ImportantPerson()
}
private func resolve() -> Order {
return LastOrder()
}
}
let a = A()
let client: Client = a.resolveDependency()
let order: Order = a.resolveDependency()
print("Client: \(client.description)")
print("Order: \(order.description)")
編輯 :這個問題與Swift是否允許創建兩個僅返回類型不同的函數無關。 我知道有可能 我認為編譯器中存在一些人為的約束,但基本邏輯中沒有,應允許從上下文中推斷所需的類型。
讓我們投入到編譯器的工作中。 想象一下,這沒有引起錯誤,並且您有一個簽名和不同的輸出。
每當您調用resolveDependency<T>() -> T
,編譯器都會為您返回類型T
,該類型T
是符合您所用協議的實例。
在您的代碼中,使用符合同一協議的不同實例調用此方法。 在那個階段,編譯器對此還一無所知。 它只知道你已經通過實例T
,它需要給你的形狀結果T
到現在為止沒有問題。 一旦執行
return resolve() as! T
編譯器會感到困惑。 我有一個T
但是我不知道我將調用哪個resolve()
...我所知道的就是我有一個T
我怎么知道這是Order
還是Client
?
為了避免此類混淆,我們存在編譯時錯誤。 至少Swift就是這種情況。 (我不知道其他語言的工作原理)
您需要使用不同的簽名定義不同的方法,並相應地轉換類型以獲得相似的結果
fileprivate func resolveDependency<T>() -> T {
// check if this is an Order
resolveForOrder()
// check if this is a Client
resolveForClient()
}
private func resolveForOrder() -> Order {
return LastOrder()
}
private func resolveForClient() -> Client {
return ImportantPerson()
}
這就像試圖用汽車修理工修理航天飛機發動機一樣。 是的,他們倆都有發動機,都以燃料為動力,但是機械師只知道如何修理汽車發動機,因為他不是火箭科學家(!)
這段代碼可以正常工作:
import Foundation
protocol Client: class {
var description: String { get }
}
final class ImportantPerson : Client {
var description: String {
return "Important person"
}
}
protocol Order: class {
var description: String { get }
}
final class LastOrder : Order {
var description: String {
return "Last order"
}
}
final class A {
fileprivate func resolveDependency<T>() -> T {
if T.self == Client.self {
return resolve() as Client as! T
} else {
return resolve() as Order as! T
}
}
private func resolve() -> Client {
return ImportantPerson()
}
private func resolve() -> Order {
return LastOrder()
}
}
let a = A()
let client: Client = a.resolveDependency()
let order: Order = a.resolveDependency()
print("Client: \(client.description)")
print("Order: \(order.description)")
但是我相信編譯器應該自己解決if else子句,這並不像我想的那么難。 另外,當編譯器嘗試匹配以下類型時,還會出現一些錯誤:
switch T.self {
case is Client:
return resolve() as Client as! T
default:
return resolve() as Order as! T
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.