【发布时间】:2018-08-16 13:01:43
【问题描述】:
情况
我有两个通用类,它们将从 api 和数据库中获取数据,分别是 APIDataSource 和 DBDataSource
-
创建视图模型时,我将在视图模型中注入两个类中的任何一个,视图模型将使用该类来获取所需的数据。我希望视图模型与这两个类完全相同。所以我不希望类有不同的通用约束
// 须藤代码
ViewModel(APIDataSource
(...)) // 我想在未来改变数据源,比如
ViewModel(DBDataSource
(...)) 要从 api ResponseModel 获取数据,需要确认“可解码”,因为我想从 JSON 创建该对象。要从领域数据库中获取数据,它需要从 Object 继承
-
在 ViewModel 中我想得到类似的响应
// 须藤代码
self.dataSource.request("param1", "param2")
如果开发人员试图从数据库中获取 api 数据,反之亦然,它将检查类型是否正确并引发正确的错误。
游乐场代码的剥离版本
以下是代码的剥离版本,它显示了我想要实现的目标或我卡在哪里(将不受约束的泛型类型转换为确认可解码的泛型类型)
import Foundation
// Just to test functions below
class DummyModel: Decodable {
}
// Stripped out version of function which will convert json to object of type T
func decode<T:Decodable>(_ type: T.Type){
print(type)
}
// This doesn't give compilation error
// Ignore the inp
func testDecode<T:Decodable> (_ inp: T) {
decode(T.self)
}
// This gives compilation error
// Ignore the inp
func testDecode2<T>(_ inp: T){
if(T.self is Decodable){
// ??????????
// How can we cast T at runtime after checking T confirms to Decodable??
decode(T.self as! Decodable.Type)
}
}
testDecode(DummyModel())
将不胜感激任何帮助或解释这不起作用。在此先感谢:)
【问题讨论】:
-
最后(对不起,这是最后一条评论,我保证),我怀疑这是stackoverflow.com/questions/33112559/…的另一个案例
-
嗨,马特,感谢您的快速回复,以下是对您的问题的回复 1. 我想为其他类型的对象使用相同的类并为其用户提供相同的界面,所以我不能使用 Decodable 约束2. 上面的代码过于简单,我实际上想将 JSON 解码为 T 3。是的,这两个问题的原因似乎是相同的,可能有一些解决方法
-
“在获取数据的方法中,我将检查泛型类型的类型,如果它确认“可解码”协议,我将使用它从数据库中的 api 获取数据。”这是一个非常奇怪的语义。您是说如果有人让您的任何数据库模型可解码(可能出于不相关的原因),您是否希望它改变调用者访问网络的行为?如果另一个模块将
Decodable添加到现有类型怎么办? -
我强烈建议将有关数据来自何处的信息放入对象中(例如,作为类或实例常量)。然后在运行时检查以决定要做什么。不要试图依赖协议一致性。一旦将泛型添加到组合中,该信息在运行时就不可靠了。
-
这不清楚:“我将在视图模型中注入两个类中的任何一个,而视图模型将使用该类来获取所需的数据。”模型类是否已经存在并使用加载器来获取数据,或者加载器是否应该生成模型?我相信你是在倒退设计这个系统,所以你的问题最终会问错问题。不过,目前还不清楚调用代码应该是什么样子(使用这个“加载器/模型”系统的东西)。
标签: swift generics casting decode