gpt4 book ai didi

swift - 如何通过完成和 resultType 获得泛型?

转载 作者:行者123 更新时间:2023-11-28 13:32:18 25 4
gpt4 key购买 nike

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

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

我很感激任何帮助!

方法#1

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

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
}

...

}
}

🆘 错误:协议(protocol)“DataApiAccess”只能用作通用约束,因为它具有 Self 或关联类型要求

最佳答案

您不能设置可变通用协议(protocol),但您可以设置方法

示例代码如下

  • 为基本结果创建枚举:

    enum DataResult<T> {
    case success(T)
    case failure(Error)
    }

    ///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#>)
}


}

尽情享受吧!

关于swift - 如何通过完成和 resultType 获得泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57166352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com