【问题标题】: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
    }

}

【问题讨论】:

    标签: swift generics protocols opaque-types


    【解决方案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,并且无法将其用作返回类型。
      • 是的,所以我无法返回通用协议,因为它有自我要求,并且只能用作通用约束。很烦人,我发现通用协议几乎没用:/
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      相关资源
      最近更新 更多