声明包含泛型案例的枚举的返回值?
Posted
技术标签:
【中文标题】声明包含泛型案例的枚举的返回值?【英文标题】:Declaring a return value of enum containing a case with a generic type? 【发布时间】:2018-01-23 18:48:42 【问题描述】:我有一个简单的网络结果枚举。如果调用成功,我将使用请求类型的对象返回成功。如果不成功,我会返回失败信息。
enum Result<T>
case success(T)
case failure(String)
func testAPI(requestedObjClass: String) -> Result ...
使用此代码,编译器会给出错误:
Reference to generic type 'Result' requires arguments in <...>
它希望我用Result<MyObj>
之类的东西定义“成功”案例的类型,但根据参数的不同,它可能是不同的类型,我什至可能根本不会返回成功。这个“结果”想法的正确架构是什么?
【问题讨论】:
【参考方案1】:编译器需要在编译时解析泛型类型占位符值。例如,在
if case .success(let res) = testAPI(requestedObjClass: "...")
print(res)
编译器需要知道res
的类型。因此你不能
返回一个 Result
,其中对应的 T
仅在运行时确定。
可能的解决方案是将请求的结果类型作为 一个类型而不是一个字符串,并使函数泛型:
func testAPI<T>(requestedObjClass: T.Type) -> Result<T>
// ...
然后在像这样的电话中
if case .success(let res) = testAPI(requestedObjClass: Int.self)
print(res)
编译器可以推断出类型T
(从而推断出结果的类型
编译时的值res
),在本例中为Int
。
【讨论】:
你也许可以完全删除requestedObjClass
,但我不确定Swift编译器是否足够聪明,可以从if case.success(let res: Int) = testAPI()
推断类型
@Samah:类型可以从上下文中推断出来,例如在let res: Result<Int> = testAPI()
中,但if case success(let res as Int) = testAPI()
无法编译。我还是更喜欢let res = testAPI(Int.self)
。【参考方案2】:
它希望我用一些东西来定义“成功”案例的类型 像结果,但它可能是不同的类型,具体取决于 论据
您可以编写一些协议,例如 MyProtocol
,然后使用此协议扩展 MyObj
和所有其他需要的类,例如
class MyObj
protocol MyProtocol
extension MyObj: MyProtocol
extension Int: MyProtocol
enum Result<T>
case success(T)
case failure(String)
func testAPI(requestedObjClass: String) -> Result<MyProtocol>
return .failure("Not implemented")
一般来说,为MyProtocol
形成一些约束是个好主意,比如方法或计算变量。拥有过于动态的东西不是很快速的方式。
【讨论】:
以上是关于声明包含泛型案例的枚举的返回值?的主要内容,如果未能解决你的问题,请参考以下文章