Swift (type:T.type)使泛型方法工作,而没有泛型方法,则无法推断T

Swift (type:T.type)使泛型方法工作,而没有泛型方法,则无法推断T,swift,generics,types,Swift,Generics,Types,我使用一个简单的方法在我的核心数据数据库上运行一个fetch请求。我将我的大部分代码放在一个协议中,该协议将有默认的实现,某些东西将进行扩展。我的代码如下: protocol Modelable { func testFetch<T>(type: T.Type) -> [T]? } extension Modelable { func testFetch<T>(type: T.Type) -> [T]? { let fetch

我使用一个简单的方法在我的核心数据数据库上运行一个fetch请求。我将我的大部分代码放在一个协议中,该协议将有默认的实现,某些东西将进行扩展。我的代码如下:

protocol Modelable {
    func testFetch<T>(type: T.Type) -> [T]?
}

extension Modelable {
    func testFetch<T>(type: T.Type) -> [T]? {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Data"),
            result = try? context.fetch(fetchRequest)
    
        return result as? [T]
    }
}
这段代码的奇怪之处在于,如果我从方法定义中删除
type:T.type
,并在我调用它的地方,我将得到以下错误:

无法推断泛型参数“T”


将类型传递到该方法中究竟是如何使其工作的?这不只是方法本身的一个参数吗?传递或不传递都不会改变任何东西。

如果不想传递类型,可以这样做

let modelableExtended = ModelableExtended()
let result: [SomeType]? = modelableExtended.testFetch()
print(result)
在某些时候,您必须通过传入引用它的某个参数或分配结果来说明
T
是什么

泛型是编译时特性。也许您认为它们就像
Any
AnyObject
一样,您永远不必说出类型,然后您可以在运行时找到您实际拥有的内容。这不是泛型的工作方式


泛型允许您编写可以处理许多不同类型的代码,但实际运行的代码使用的是从其上下文推断的特定类型。如果无法推断,则代码将不会编译且永远不会运行。

如果您不告诉Swift什么是
t
,则
result
应转换为哪种类型的数组,在
result as中?[T] 
?我对你说的有点困惑,但我想说的是,如果我遗漏了类型为
的testFetch()的参数:T.type
,它将抛出无法推断的
错误,而如果我包含该属性,它将转换为我传入的类型。我不明白这个参数是如何决定
t
的类型的,对,
SomeType.self
的类型是
SomeType.type
。您正在将
SomeType.Type
传递给需要
T.Type
的方法,因此
T
现在由
SomeType
限定。没有其他信息或其他类型参数,所以我们就完成了
T
被推断为它的唯一绑定-
SomeType
。你想要比这更多的实施细节吗?还有。。。。如果您没有此参数,那么T没有绑定(并且您会得到错误)。我发布了一个答案,展示了如何尝试绑定返回类型,而不是
[T]?
提供了您需要的所有详细信息。依我看,如果你只是想“绕着泛型转”,那么我建议你不要深入到实现中去。“这里有一个方法可以接受任何
T.Type
。你给它一个
SomeType.Type
。啊,
T
SomeType
!”不要担心编译器是如何做的,只要你在自然语言层面上有意义,您理解类型推断。因此,通过参考
T.type
Swift在后台处理它来确定实际的类型是什么?它在编译时发生。当你使用一个泛型-你是说-在某一点上-当我实际使用这个时,我会告诉你T到底是什么。您通常通过提供一个与模式匹配的参数来实现这一点,以便可以计算出T。但是,您也可以通过将返回值赋给一个已知类型的变量来实现。@JoeScotto Swift是一种类型推断语言。您可以说
let result:[SomeType]=modelableExtended.testFetch()
或者
let result=modelableExtended.testFetch()为[SomeType]
我更喜欢显式设置type@LeoDabus但这在幕后是如何做到的呢?我感到困惑的是,Swift如何准确地推断出特定参数作为
T
的类型。您正在显式地设置结果类型。与
let double:double=2的方式相同
let modelableExtended = ModelableExtended()
let result: [SomeType]? = modelableExtended.testFetch()
print(result)