无法使用类型的协议在Swift中工作

时间:2014-12-23 10:52:45

标签: swift

尝试使用以下代码在Swift中构建概念验证库:

import Foundation

protocol Resolver {
    typealias ResolvedType
    func get() -> ResolvedType
}

class FunctionResolver<T>: Resolver {
    typealias ResolvedType = T

    private var _resolver: () -> ResolvedType

    init(resolver: () -> ResolvedType) {
        _resolver = resolver
    }

    func get() -> ResolvedType {
        return _resolver()
    }
}


func singleton<T, U: Resolver where U.ResolvedType == T>(instance: T) -> U {
    return FunctionResolver({ () -> T in instance }) as U
}

class TestObject {
    init() { }
}

let obj = TestObject()
let r = singleton(obj)

然而,最后一行失败了:

playground466.swift:30:9: error: cannot convert the expression's type 'TestObject' to type 'Resolver'
let r = singleton(obj)
        ^~~~~~~~~

为什么Swift会尝试将obj转换为Resolver?我不太清楚我在那里失踪了什么。我认为这应该有效,因为所有类型信息都在singleton方法中可用。

我是否在推理系统中引入了某种循环?如何修复此问题,以便最后一行按预期工作(解析为obj的同一实例的解析器)?

我正在访问开发门户网站上的最新Xcode。


编辑:我尝试过简化它,但仍无效:

func singleton<T: Resolver>(instance: T.ResolvedType) -> T {
    return FunctionResolver(resolver: { () -> T.ResolvedType in instance }) as T
}

2 个答案:

答案 0 :(得分:2)

问题在于此功能:

func singleton<T, U>(instance: T) -> U {
    return FunctionResolver({ () -> T in instance }) as U
}
无法将

U推断为输入参数 - 而是指定用于推断类型的返回值的变量类型。如果你写:

let r = singleton(obj)

您没有提供足够的信息来确定U是什么。所以你应该明确指定它的类型:

let r: FunctionResolver<TestObject> = singleton(obj)

我知道......错误信息没有多大帮助:)作为一般规则,如果没有意义,问题就出在其他地方。

答案 1 :(得分:1)

您似乎正在推动类型推理系统超越它的限制。

singleton()函数使用泛型类型进行参数化,并返回该泛型类型的值。从来没有任何关于T实际上是什么类型的信息。

最简单的修复,因为Swift不支持在函数中明确提供泛型值,是确定返回类型。

let obj = TestObject()
let r : FunctionResolver = singleton(obj)

正常工作。

但是,如果您不想指定确切的类型,只需要r is Resolver

运气好。斯威夫特并不支持这一点。具有关联类型的协议只能用作通用约束,因为编译器错误状态。