通用类型与同一类型不同

Ric*_*ich 3 generics swift

我有以下内容(我已将其简化为最基本的情况):

class Something<H: Hashable> {

}

func function<H: NSDate>() -> Something<H> {
    let s: Something<NSDate> = Something()
    return s
}
Run Code Online (Sandbox Code Playgroud)

错误就return s行了:

NSDate与'H'不同

但这没有任何意义,因为这应该允许任何子类NSDateNSDate自身.

例如,以下工作:

let dateSomething: Something<NSDate> = Something()
functionWorks(dateSomething)

func functionWorks<H: NSDate>(parameter: Something<H>) {

}
Run Code Online (Sandbox Code Playgroud)

有没有人有任何想法为什么第一个例子不起作用?我目前认为这可能是Swift本身的一个问题......

ric*_*ter 5

通用类型参数不统一.仅在专门化泛型时才检查类型约束,否则thing<T>尖括号内的两个具有不同内容的类型是完全不相关的类型,即使尖括号内的事物本身是相关类型.

换句话说:Swift泛型是类型保留的.如果有人打电话function<SubclassOfNSDate>(),它需要返回Something<SubclassOfNSDate>,而不是Something<NSDate>.要返回后者,将删除调用者提供的类型.(其他一些语言使用类型擦除做泛型,所以你可以在那里做.虽然类型擦除系统有其他缺点,所以Swift不会这样做.)

从你发布的内容中很难看出你真正想要实现的目标.更改此行至少应该使其编译,但是:

let s: Something<H> = Something()
Run Code Online (Sandbox Code Playgroud)

这样你就H可以NSDate从函数的泛型参数中使用(恰好是)(这是你期望返回的).


Rob*_*ier 5

回到你所要求的:

func function<H: NSDate>() -> Something<H> {
Run Code Online (Sandbox Code Playgroud)

正如Nate和rickster所说,由于Swift的类型规则,这不起作用.但它也不是你的意思.没有理由使用类型参数化来指示一种特定类型.你不需要说"H,其中H是NSDate." 你应该说"NSDate".你真正的意思是:

func function() -> Something<NSDate> {
Run Code Online (Sandbox Code Playgroud)

这将很好.事实上,由于类型推断,它甚至更简单:

func function() -> Something<NSDate> {
    return Something()
}
Run Code Online (Sandbox Code Playgroud)