我有以下内容(我已将其简化为最基本的情况):
class Something<H: Hashable> {
}
func function<H: NSDate>() -> Something<H> {
let s: Something<NSDate> = Something()
return s
}
错误发生在return s
行:
NSDate与'H'
不同
但这没有任何意义,因为NSDate
或NSDate
本身的任何子类都应该被允许。
例如以下作品:
let dateSomething: Something<NSDate> = Something()
functionWorks(dateSomething)
func functionWorks<H: NSDate>(parameter: Something<H>) {
}
有没有人有任何想法为什么第一个例子不起作用?我目前认为这可能是Swift本身的一个问题......
答案 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
}