通用类型与同一类型不同

时间:2015-02-20 15:19:58

标签: swift generics

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

class Something<H: Hashable> {

}

func function<H: NSDate>() -> Something<H> {
    let s: Something<NSDate> = Something()
    return s
}

错误发生在return s行:

  

NSDate与'H'

不同

但这没有任何意义,因为NSDateNSDate本身的任何子类都应该被允许。

例如以下作品:

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

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

}

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

3 个答案:

答案 0 :(得分:5)

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

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

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

let s: Something<H> = Something()

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

答案 1 :(得分:5)

回到你所要求的:

func function<H: NSDate>() -> Something<H> {

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

func function() -> Something<NSDate> {

这样可以正常工作。事实上,由于类型推断,它甚至更简单:

func function() -> Something<NSDate> {
    return Something()
}

答案 2 :(得分:4)

它不起作用,因为调用函数的特定子类型H可能是NSDate子类:

// subclass NSDate
class SpecialDate : NSDate { }

// this needs a Something<SpecialDate> returned, not a Something<NSDate>
let specialSomething: Something<SpecialDate> = function()

解决方案是在您的函数中使用H子类型Something

func function<H: NSDate>() -> Something<H> {
    let s: Something<H> = Something()
    return s
}