声明包含泛型案例的枚举的返回值?

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&lt;MyObj&gt; 之类的东西定义“成功”案例的类型,但根据参数的不同,它可能是不同的类型,我什至可能根本不会返回成功。这个“结果”想法的正确架构是什么?

【问题讨论】:

【参考方案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&lt;Int&gt; = 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 形成一些约束是个好主意,比如方法或计算变量。拥有过于动态的东西不是很快速的方式。

【讨论】:

以上是关于声明包含泛型案例的枚举的返回值?的主要内容,如果未能解决你的问题,请参考以下文章

java 判断返回值为枚举类型

Java 泛型

泛型基本概念

通过泛型类中嵌套枚举的反射获取枚举值

Swift 在一行中返回关联的枚举值或 nil

8.4 泛型方法