我需要一个函数来解决类中的不同依赖项。 但是出现了编译错误。 是否有可能创建该泛型函数或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是否允许创建两个仅由返回类型不同的函数。我知道这是可能的。我认为在编译器中存在一些人为约束,但在基本逻辑中不应该允许从上下文中推断出所需的类型。
答案 0 :(得分:0)
让我们把自己置于编译器之中。想象一下,这不会导致错误,并且您有一个具有不同输出的签名。
每当你调用resolveDependency<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()
}
这就像试图用汽车修理工修理航天飞机发动机一样。是的,他们都有一个引擎,他们都使用燃料,但机械师只知道如何修理你的汽车发动机他不是火箭科学家(!)
答案 1 :(得分:0)
此代码可以正常工作:
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
}