Swift协议通用作为函数返回类型 [英] Swift protocol generic as function return type

查看:465
本文介绍了Swift协议通用作为函数返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用泛型协议类型作为函数返回类型,如下所示:

I want to use generic protocol type as a function return type like this:

protocol P {
  associatedtype T
  func get() -> T?
  func set(v: T)
}

class C<T>: P {
  private var v: T?
  func get() -> T? {
    return v
  }
  func set(v: T) {
    self.v = v
  }
}

class Factory {
  func createC<T>() -> P<T> {
    return C<T>()
  }
}

但是这段代码编译出错,抱怨:

But this code compile with errors complained:


  1. 无法专用非泛型类型'P'

  2. 函数签名中不使用泛型参数'T'
  1. Cannot specialize non-generic type 'P'
  2. Generic parameter 'T' is not used in function signature

是否有任何方法可以实现与Swift类似的功能?

Is there any way to achieve similar function with Swift?

推荐答案

问题是您无法使用语法 P< T> P 是一个协议,这意味着它不能被当作泛型类型(不能专用非泛型类型'P' associatedtype

The problem is you cannot use the syntax P<T>. P is a protocol, meaning it can't be treated as a generic type (Cannot specialize non-generic type 'P'), even though it may have a given associatedtype.

事实上,因为它有一个 associatedtype ,你现在甚至不能直接使用协议类型 - 你只能用它作为通用约束。

In fact, because it has an associatedtype, you now can't even use the protocol type itself directly – you can only use it as a generic constraint.

解决您的问题仅仅是将您的函数签名更改为 createC< T>() - >

The solution to your problem is simply to change your function signature to createC<T>() -> C<T>, as that's exactly what it returns!

class Factory {
    func createC<T>() -> C<T> {
        return C<T>()
    }
}

我不完全确定你认为你能从这里返回一个协议类型而获得什么。如果你的代码只是一个简化,并且你希望能够返回一个符合 P 的任意实例,你可以使用 type erasure

I'm not entirely sure what you think you would gain from being able to return a protocol type here. If your code is just a simplification and you want to be able to return an arbitrary instance that conforms to P, you could use a type erasure.

class AnyP<T> : P {

    private let _get : () -> T?
    private let _set : (T) -> ()

    init<U:P where U.T == T>(_ base:U) {
        _get = base.get
        _set = base.set
    }

    func get() -> T? {return _get()}
    func set(v: T) {_set(v)}
}



class Factory {
    func createC<T>() -> AnyP<T> {
        return AnyP(C<T>())
    }
}

这篇关于Swift协议通用作为函数返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆