【发布时间】:2020-09-24 01:14:57
【问题描述】:
我很难理解泛型。我想要的是拥有一组泛型类,每个类都有自己的关联类型,并相应地调用一个函数。它看起来像这样:
class SomeGenericClass<U> {
func addCallback(callback: (U)->() ) { ... }
}
var array: [SomeGenericClass] // compile error
最后一行产生了一个错误,所以我发现我需要一个超类。我尝试过这样的事情:
class SuperClass {
func addCallback<V>(callback: (V)->() ) { ... }
}
class SomeGenericClass<U> {
func addCallback<V: U>(callback: (V)->() ) { ... } // compile error
}
var array: [SuperClass] // no compile error
这会产生错误Type 'V' constrained to non-protocol, non-class type 'U'。
基本上我希望能够做到:
array.append(SomeGenericClass<UIImage>()) // array[0]
array.append(SomeGenericClass<Int>()) // array[1]
// Since array[0] is effectively of type SomeGenericClass<UIImage>, the compiler should understand that the close added if of type (UIImage)->(), and therefore that value is of type UIImage
array[0].addCallback { value in
someImageView.image = value
}
在这种情况下使用超类是正确的方法吗?应该如何实现?
【问题讨论】:
-
感谢您提供您的最终目标。那是不可能的。
value必须有一个在编译时已知的类型。您不必写下类型这一事实并不意味着编译器不必知道它是什么。鉴于您对它的类型一无所知,您接下来会编写哪行代码使用value?尝试编写一个真正适用于此的回调块,并且做的不仅仅是调用print(value),记住我可以将array[0]更改为我想要的任何东西,并且您的代码仍然必须工作。 -
了解泛型的最佳方法是从有重复的具体代码开始。然后研究如何使用泛型删除重复项。从泛型开始,然后试图找到如何使用它们几乎总是会让你陷入困境。所以在一个没有泛型的世界里,你只需要为每种类型复制代码,你会在这里写什么?
-
感谢您的评论。我更新了我想要的代码。这根本不可能吗?我们有什么可能的解决方法?
-
我认为重要的是还要注意我的数组是恒定的,它在惰性变量中定义并且不会改变 - 实际上,它是一个字典。因此,当我访问一个元素时,我肯定知道它将是什么类型。也许我们可以利用它,改变结构类型?
-
但是如果
array[0]元素是SomeGenericClass<Int>那么你为什么需要someImageView.image = value。在这种情况下,value将是Int类型。
标签: arrays swift generics inheritance