简体   繁体   English

返回专用类型的通用协议 swift 的方法

[英]Method to return specialised type of generic protocol swift

I have a generic protocol which has a method that returns the generic parameter.我有一个通用协议,它有一个返回通用参数的方法。 There are two implementations of the protocol that both have string as the return type.该协议有两种实现,它们都将字符串作为返回类型。 I want a method to build a particular instance similar to a class cluster based on some parameter.我想要一种基于某些参数构建类似于类集群的特定实例的方法。 The method constrains the generic type but there is an error when trying to return:该方法约束了泛型类型,但尝试返回时出现错误:

"Cannot convert return expression of type StringReturn into return type T" “无法将 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
    }

}

What you are trying to achieve is to use a generic function to create a instance of an object using Swift's Type Constraints.您想要实现的是使用泛型函数使用 Swift 的类型约束创建对象的实例。

Note the general syntax from Apple's documentation:请注意 Apple 文档中的一般语法:

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

In you function, it's not possible to infer at the time of function execution what type T is because you aren't passing it to the function as a parameter, hence you can't say what type is the output.在您的函数中,无法在函数执行时推断T是什么类型,因为您没有将其作为参数传递给函数,因此您无法说出输出是什么类型。

If you want to use a generic function with type constraints you could add some init to your protocol and use a function like this:如果你想使用带有类型约束的泛型函数,你可以在你的协议中添加一些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")

Hope it helps!希望能帮助到你!

It is possible to achieve using Opaque Types rather than Protocol generics at newest Swift versions.在最新的 Swift 版本中,可以使用不透明类型而不是协议泛型来实现。

Swift 5.3斯威夫特 5.3

You can think of an opaque type like being the reverse of a generic type.您可以将不透明类型视为与泛型类型相反的类型。 Generic types let the code that calls a function pick the type for that function's parameters and return value in a way that's abstracted away from the function implementation.泛型类型让调用函数的代码选择该函数参数的类型并以一种从函数实现中抽象出来的方式返回值。 For example, the function in the following code returns a type that depends on its caller:例如,以下代码中的函数返回一个依赖于其调用者的类型:

Apple documentation 苹果文档

Example 例子

protocol Fighter { }
struct XWing: Fighter { }

func launchFighter() -> Fighter {
    XWing()
}

let red5 = launchFighter()

It needs keyword some before your protocol name:它需要在您的协议名称之前使用关键字some

func launchOpaqueFighter() -> some Fighter {
    XWing()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM