Ios 如何在方法声明中使用关联类型

Ios 如何在方法声明中使用关联类型,ios,swift,generics,Ios,Swift,Generics,我正在构建解析服务器响应的通用方法。也许我想用一种太花哨的方式来做,但另一方面,我会在很多项目中使用它,所以也许花一些时间在它上是值得的,让我们来描述一下我的问题 我实现了响应骨架,这是一个通用类,我将从中创建对象。对象是M的类型 class ApiResponse<M: Mappable> { required init(response: Any) { // Here I'd like to do mapping according to the ho

我正在构建解析服务器响应的通用方法。也许我想用一种太花哨的方式来做,但另一方面,我会在很多项目中使用它,所以也许花一些时间在它上是值得的,让我们来描述一下我的问题

我实现了响应骨架,这是一个通用类,我将从中创建对象。对象是M的类型

class ApiResponse<M: Mappable> {  
    required init(response: Any) {
        // Here I'd like to do mapping according to the holding type
    }
}
问题是如何让科米勒快乐

下面是代码的链接


更新 经过几个小时的斗争,我已经使这个问题的工作,但我发现一些奇怪的事情

我将方法签名写为fallowing

private func getObservable<T: ApiResponse<A>, A: Mappable>(endpoint: Endpoint, t:A?=nil) -> Observable<T> where A:NSManagedObject 
private func getObservable(端点:端点,t:A?=nil)->可观察,其中A:NSManagedObject

当我删除
t:A?=nil
时,编译器不高兴。它抱怨方法签名中没有使用
A
类型。为什么会这样?为什么?为什么?为什么?

这似乎是当前Swift编译器中类型推断实现的缺陷/限制。虽然在您的示例中,期望编译器能够推断出两个嵌套级别的泛型类型约束(
A
T
)是合乎逻辑的,但我猜想这种多级推断目前还没有实现,这意味着Swift希望您在签名本身中使用所有泛型类型约束,因此,编译器可以从任何调用代码的上下文中推断出
A
T
应该是什么,而无需进行多个级别的求解,例如,无需了解:

result = PostResponse             <----->    T = PostResponse

PostResponse: ApiResponse<Post>   <----->    T: ApiResponse<Post>

Post is the inner generic type    <----->    therefore A: Post
这将在您的代码中被调用,如下所示:

var posts: Observable<PostsResponse> {
    get { return getObservable(endpoint: .posts, objectType:Post.self) }
}
var posts:可观察{
get{return getObservable(端点:.posts,对象类型:Post.self)}
}
以下是一些旁注:

  • 我认为您不需要指定
    A:Mappable
    约束,因为类声明
    class-ApiResponse
    已经声明了该需求
  • 即使您的变通示例中有一个参数的默认值为nil(
    t:a?=nil
    )会使编译器警告静音,但如果您试图实际调用代码中的某个函数,却没有收到不同的警告,我还是会感到惊讶。参数
    t:A?
    的默认值为零,这使得编译器无法直接推断
    A
    应该是什么具体类型,我在前面提到过,我认为Swift编译器无法通过先推断然后对
    t
    进行内省来推断
    A
  • private func getObservable<T: ApiResponse<A>, A: Mappable>(endpoint: Endpoint, t:A?=nil) -> Observable<T> where A:NSManagedObject 
    
    result = PostResponse             <----->    T = PostResponse
    
    PostResponse: ApiResponse<Post>   <----->    T: ApiResponse<Post>
    
    Post is the inner generic type    <----->    therefore A: Post
    
    private func getObservable<T: ApiResponse<A>, A: Mappable>(endpoint: Endpoint, objectType:A.Type) -> Observable<T> where A:NSManagedObject 
    
    var posts: Observable<PostsResponse> {
        get { return getObservable(endpoint: .posts, objectType:Post.self) }
    }