快速返回特殊类型的通用协议的方法

Posted

技术标签:

【中文标题】快速返回特殊类型的通用协议的方法【英文标题】:Method to return specialised type of generic protocol swift 【发布时间】:2016-03-21 03:29:34 【问题描述】:

我有一个通用协议,它有一个返回通用参数的方法。该协议有两种实现,它们都将字符串作为返回类型。我想要一种方法来构建类似于基于某些参数的类集群的特定实例。该方法约束了泛型类型但尝试返回时出错:

“无法将StringReturn类型的返回表达式转换为返回类型T”

protocol GenericProtocol 

    typealias ReturnType

    func doSomething() -> ReturnType



struct StringReturn : GenericProtocol 

    func doSomething() -> String 
        return "first"
    



struct AnotherStringReturn : GenericProtocol 

    func doSomething() -> String 
        return "another"
    



func build<T : GenericProtocol where T.ReturnType == String>(param: String) -> T 

    if .. 
        return StringReturn()
     else 
        return AnotherStringReturn
    


【问题讨论】:

【参考方案1】:

在最新的 Swift 版本中,可以使用不透明类型而不是协议泛型来实现。

斯威夫特 5.3

您可以将不透明类型视为泛型类型的反面。泛型类型让调用函数的代码选择函数参数的类型,并以一种从函数实现中抽象出来的方式返回值。例如,以下代码中的函数返回一个依赖于其调用者的类型:

Apple documentation

Example

protocol Fighter  
struct XWing: Fighter  

func launchFighter() -> Fighter 
    XWing()


let red5 = launchFighter()

在你的协议名称前需要关键字some

func launchOpaqueFighter() -> some Fighter 
    XWing()

【讨论】:

【参考方案2】:

您想要实现的是使用通用函数来使用 Swift 的类型约束创建对象的实例。

注意 Apple 文档中的一般语法:

func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) 
  // function body goes here

在您的函数中,无法在函数执行时推断 T 是什么类型,因为您没有将它作为参数传递给函数,因此您无法说出输出是什么类型。

如果您想使用具有类型约束的通用函数,您可以在协议中添加一些 init 并使用如下函数:

func build<T : GenericProtocol where T.ReturnType == String>(object: T.Type, param: String) -> T 
  // Your code here
  return T.init()


let str = build(StringReturn.self, param: "name")

希望对你有帮助!

【讨论】:

嗨,这很好,但我希望函数决定 T 最终是什么,这可能吗? @LukeDeFeo 如果你想根据某些条件返回一个对象,我想你可以使用一个常规函数,GenericProtocol 作为返回类型。问题是您的协议有一个关联类型ReturnType,并且无法将其用作返回类型。 是的,所以我无法返回通用协议,因为它有自我要求,并且只能用作通用约束。很烦人,我发现通用协议几乎没用:/

以上是关于快速返回特殊类型的通用协议的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Java 方法返回任何类型的通用列表?

推断函子返回类型的通用方法?

java - 通用返回类型? [复制]

“通用类型系统”(CTS)

符合自定义协议的通用函数 - Swift

通用方法签名