首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得具有完成性和resultType工作的泛型?

如何获得具有完成性和resultType工作的泛型?
EN

Stack Overflow用户
提问于 2019-07-23 14:25:04
回答 1查看 130关注 0票数 0

我目前正在为两个数据库API编写和数据库访问类(王国和Firestore)。为了精简代码,我尝试用泛型解决整个问题(#1)。不幸的是它不起作用了。我在哪里错过了重点?

我尝试定义关联类型(#2)并在RealmAccessStragy类中设置它们。但在这一点上,如果试图通过PersistenceController访问协议,编译器将返回错误。

我很感谢你的帮助!

方法#1

代码语言:javascript
复制
enum DataResult<T> {
    case success(T)
    case failure(Error)
}

protocol DataApiAccess: AnyObject {
func read<U, T>(primaryKey: U, completion: @escaping ((DataResult<T>) -> Void))
}

class RealmAccessStrategy {
    ...
    func read<U, T>(primaryKey: U, completion: @escaping ((DataResult<T>) -> Void)) {
        guard let realmObject = realmInstance.object(ofType: realmObjectType, forPrimaryKey: primaryKey) else {
            completion(.failure(RealmAccessError.noObject))
            return
        }

        completion(.success(realmObject)) // ERROR: Member 'success' in 'DataResult<_>' produces result of type 'DataResult<T>', but context expects 'DataResult<_>'
    }
}


// Later implementation
class PersistenceController {
    private let strategy: DataApiAccess

    init(use: DataApiAccess) {
        self.strategy = use
    }

    func load<U, T>(primaryKey: U, completion: @escaping ( (DataResult<T>) -> Void ) ) {
        strategy.read(primaryKey: primaryKey, completion: completion)
    }
}

'DataResult<>‘中的错误:成员“成功”生成'DataResult’类型的结果,但上下文要求'DataResult<>'

方法#2

代码语言:javascript
复制
enum DataResult<T> {
    case success(T)
    case failure(Error)
}

protocol DataApiAccess {
    associatedtype ReturnType

    func read(primaryKey: PrimaryKeyType, completion: @escaping DataApiHandler<ReturnType>)
}

class RealmAccessStrategy: DataApiAccess {

    ...

    // Typealias
    internal typealias ReturnType = Object

    func read(primaryKey: Any, completion: @escaping ((DataResult<Object>) -> Void)) {
        guard let realmObject = realmInstance.object(ofType: realmObjectType, forPrimaryKey: primaryKey) else {
            completion(.failure(RealmAccessError.noObject))
            return
        }

        completion(.success(realmObject))
    }
}


class PersistenceController {
    private let strategy: DataApiAccess // ERROR: Protocol 'DataApiAccess' can only be used as a generic constraint because it has Self or associated type requirements

    init(use: DataApiAccess) {
        self.strategy = use
    }

    ...

    }
}

错误:协议'DataApiAccess‘只能用作泛型约束,因为它具有自或关联类型需求

EN

回答 1

Stack Overflow用户

发布于 2019-07-23 14:50:57

不能设置变量泛型协议,但可以设置方法

示例代码在下面

  • 为基本结果创建枚举: 枚举DataResult {案例成功(T)失败(错误)}
代码语言:javascript
复制
    ///Set a protocol generic methods:
    protocol DataApiAccess {
        func read<T: Codable>(primaryKey: PrimaryKeyType, completion: @escaping (DataResult<T>) -> Void)
    }

    class RealmAccessStrategy: DataApiAccess {

        func read<T: Codable>(primaryKey: PrimaryKeyType, completion: @escaping (DataResult<T>) -> Void) {
            // Read data from database
        }
    }

    class NetworkAccessStrategy: DataApiAccess {


        func read<T: Codable>(primaryKey: PrimaryKeyType, completion: @escaping (DataResult<T>) -> Void) {
             // Get data from request
        }
    }

    class PersistenceController {

        private let strategy: DataApiAccess

        init(use: DataApiAccess) {
            // Set dependency inversion for offline or online state
            self.strategy = use
        }

        func foo() {
             // TODO
            //strategy.read(primaryKey: <#T##PrimaryKeyType#>, completion: <#T##(DataResult<Decodable & Encodable>) -> Void#>)
        }


    }

享受吧!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57166352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档