是否可以将类型擦除应用于协议中的返回值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否可以将类型擦除应用于协议中的返回值?相关的知识,希望对你有一定的参考价值。

好了,标题可能有点含糊不清,但基本上,我想要实现的目的如下:假设我有两个类用于从后端获取数据,它们都缓存了获取的数据,因此,他们都有invalidateCache()方法。由于它们用于数据提取,因此它们中的每一个都有一个返回不同类型对象的方法fetch()

class UserManager {
    ...
    func invalidateCache() {
        ...
    }
    func fetch() -> [User] {
        ...
        return users
    }
}

class PostManager {
    ...
    func invalidateCache() {
        ...
    }
    func fetch() -> [Post] {
        ...
        return posts
    }
}

然后我有一个基本视图控制器和两个继承的视图控制器(例如,UsersViewControllerPostsViewController),我实际上使用它。这两个视图控制器使用相应的实体管理器我想要一些通用协议,它将是基本视图控制器中的一种属性,每个继承的协议都有特定的实现,如下所示:

protocol EntityManager<Result>: class {
    func invalidateCache()
    func fetch() -> [Result]
}

class UserManager: EntityManager<User> {
    ...
    func fetch() -> [User] {
        ...
    }
}

class PostManager: EntityManager<Post> {
    ...
    func fetch() -> [Post] {
        ...
    }
}


class BaseViewController: UIViewController {
    var manager: EntityManager?
    override func viewDidDisappear() {
        manager?.invalidateCache()
    }
}

class UserViewController: BaseViewController {
    var users: [User]?
    override func viewDidLoad() {
        super.viewDidLoad()
        manager = UserManager()
        users = manager?.fetch()
    }
}

class PostViewController: BaseViewController {
    var posts: [Post]?
    override func viewDidLoad() {
        super.viewDidLoad()
        manager = PostManager()
        posts = manager?.fetch()
    }
}

我尝试应用类型擦除但在任何方面都没有成功(我怀疑我不完全理解类型擦除的应用范围)。据我所知,swift编译器要求在编译期间类型必须是单义的,我只是不明白为什么在我的情况下存在歧义。

答案

你需要User和Post才能有共同点。例如,

protocol Fetchable { }
class User: Fetchable { }
class Post: Fetchable { }

class Manageable<T> {
    func fetch() -> [T] { return [] }
}
class UserManager: Manageable<User> {
    override func fetch() -> [User] { return [] }
}
class PostManager: Manageable<Post> {
    override func fetch() -> [Post] { return [] }
}

let users = UserManager().fetch()
print("users=(users)")
let posts = PostManager().fetch()
print("posts=(posts)")

以上是关于是否可以将类型擦除应用于协议中的返回值?的主要内容,如果未能解决你的问题,请参考以下文章

写出java中定义方法的语法格式,并说明一个方法可以有多少个参数,多少个返回值?

swift类型擦除的定义-swift的类型擦除只是一个类型高低阶转换的游戏。

Java泛型:类型擦除

我可以以编程方式擦除 applicationDidFinishLaunching:withOptions: 中的应用程序数据吗?

AndroidJava泛型的擦除

是否可以通过明文类型确定 ENCRYPTBYKEY 最大返回值?