Swift 如何键入泛型协议以将其用作返回类型

Swift 如何键入泛型协议以将其用作返回类型,swift,generics,protocols,Swift,Generics,Protocols,以下代码不起作用。 我来自Java世界,我不明白为什么只要指定typealias,就不能返回泛型协议 我尝试在UserDao中对其进行专门化,但每次getTest()方法都返回相同的错误: 协议“UserDao”只能用作一般约束,因为它具有自身或关联的类型要求 用swift做这件事的好方法是什么 import Foundation protocol HasId { } protocol BaseDao { associatedtype Element: HasId } protoc

以下代码不起作用。 我来自Java世界,我不明白为什么只要指定typealias,就不能返回泛型协议

我尝试在UserDao中对其进行专门化,但每次getTest()方法都返回相同的错误:

协议“UserDao”只能用作一般约束,因为它具有自身或关联的类型要求

用swift做这件事的好方法是什么

import Foundation

protocol HasId {
}

protocol BaseDao {
    associatedtype Element: HasId
}

protocol UserDao: BaseDao {
    // already tried these solutions...
    // associatedType Element: User
    // typealias Element = User
}

class User: HasId {}

class Test {
    func getTest() -> UserDao? { // Error is on the return type
        return nil
    }
}

UserDao
更改为
class
struct

class UserDao: BaseDao {
    typealias Element = User
}
编译器会给出上面的错误

不能将具有关联类型的协议用作函数参数或返回类型,因为它需要知道与协议关联的typealias

如果您来自Java世界,这似乎令人沮丧,但解决方案是使用一个类来定义与您的类型关联的typealias

protocol BaseDao {
    associatedtype Element: HasId
}

class UserDao: BaseDao {
    typealias Element = User
}

错误非常清楚地解释了这一点
协议“UserDao”只能用作一般约束,因为它具有自身或关联的类型要求
。已经解释过-请参考链接:这是一篇很好的文章,它可能会解决您的问题:这会起作用,但我想创建不同的UserDao实现:MemoryUserDao、FirebaseUserDao等等。。。。所以每个都实现了UserDao协议。但正如普雷什亚所指出的那样,在swift中实现这一点是不容易的。无论如何谢谢你@Spoke44如果这是一个新项目,你应该回顾一下你的dao架构。我曾多次编写过这种系统,也许您只能有一种Dao对象类型(每个表一种),但它提供了执行保存的方法。类似于协议“DataProxy”,其实现类似于“MemoryDataProxy”、“FirebaseDataProxy”,然后将其发送到BaseDao(作为简单协议DataProxy),然后调用DataProxy.save()或fetch()。并且您的代理只有通用实现,而不是特定于表,因此可以由dao对象提供。祝你好运
protocol BaseDao {
    associatedtype Element: HasId
}

class UserDao: BaseDao {
    typealias Element = User
}