Swift泛型函数问题.减少重复代码 [英] Swift generic functions issues. Decrease duplicating code

查看:104
本文介绍了Swift泛型函数问题.减少重复代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解如何减少重复代码的数量.我有两个几乎相同的功能.区别是下一个:

I want to understand how can decrease amount of duplicated code. I have two almost the same functions. The differences are next:

firs函数返回[ExerciseEntity]的数组,第二个函数返回[WorkoutEntity]的数组

firs function returns array of [ExerciseEntity] and second function returns array of [WorkoutEntity]

func replaceExercisesIdentifiers(from jsonObjects: [[String: Any]], transaction: BaseDataTransaction) -> [ExerciseEntity] {

        for jsonObject in jsonObjects {
            if let mobileLocalId = jsonObject["mobileLocalId"] as? String {
                if mobileLocalId.contains("<x-coredata://") {
                    if let managedObject = try? transaction.fetchOne(From<ExerciseEntity>()
                        .where(
                            format: "%K == %@",
                            #keyPath(BaseMO.id),
                            mobileLocalId)
                        ) {
                        let editObject = transaction.edit(managedObject)
                        if let identifier = jsonObject["id"] as? String {
                            editObject?.id = identifier
                        }
                    }
                }
            }
        }

        let managedObjects = try! transaction.importUniqueObjects(
            Into<ExerciseEntity>(),
            sourceArray: jsonObjects)

        return managedObjects
    }

    func replaceWorkoutsIdentifiers(from jsonObjects: [[String: Any]], transaction: BaseDataTransaction) -> [WorkoutEntity] {

        for jsonObject in jsonObjects {
            if let mobileLocalId = jsonObject["mobileLocalId"] as? String {
                if mobileLocalId.contains("<x-coredata://") {
                    if let managedObject = try? transaction.fetchOne(From<WorkoutEntity>()
                        .where(
                            format: "%K == %@",
                            #keyPath(BaseMO.id),
                            mobileLocalId)
                        ) {
                        let editObject = transaction.edit(managedObject)
                        if let identifier = jsonObject["id"] as? String {
                            editObject?.id = identifier
                        }
                    }
                }
            }
        }

        let managedObjects = try! transaction.importUniqueObjects(
            Into<WorkoutEntity>(),
            sourceArray: jsonObjects)

        return managedObjects
    }

这是类似的

This is a similar question related to how to use generic function I asked before.

我在代码中实现了这一点,但是:

I implemented this in my code but:

func importArray<T: ImportableUniqueObject>(from exercisesDict: [[String: Any]], transaction: BaseDataTransaction) -> [T] where T.ImportSource == [String: Any] {
    let managedObjects = try? transaction.importUniqueObjects(Into<T>(), sourceArray: jsonObjects)
}

但这是T型的几件事

首先-我无法添加此代码:editObject?.id = identifier

First - I can't add this code: editObject?.id = identifier

,因为T type中没有id.

第二次在每次崩溃时调试这些通用函数调试器:

Second when I debug these generic functions debugger every time crashes:

Message from debugger: The LLDB RPC server has crashed. The crash log is located in ~/Library/Logs/DiagnosticReports and has a prefix 'lldb-rpc-server'. Please file a bug and attach the most recent crash log.

如果有趣的话,是带有日志的文件.我还没有提交.

If interesting here is a file with log. I have not submitted it yet.

可以肯定的是,我可以添加很多打印来跟踪行为,尽管这很烦人.)但是主要任务是摆脱重复.

For sure I can add a lot of prints to track behavior, though it's a but annoying) But main task is to get rid of duplication.

推荐答案

尝试一下(我尚未测试):

Try this (I have not tested):

protocol MyProtocol {
    var id: Int { get set }
}

struct ExerciseEntity {
    var id: Int
}    

struct WorkoutEntity {
    var id: Int
} 

func replaceWorkoutsIdentifiers<T: MyProtocol>(from jsonObjects: [[String: Any]], transaction: BaseDataTransaction) -> [T] {

    for jsonObject in jsonObjects {
        if let mobileLocalId = jsonObject["mobileLocalId"] as? String {
            if mobileLocalId.contains("<x-coredata://") {
                if let managedObject = try? transaction.fetchOne(From<T>()
                    .where(
                        format: "%K == %@",
                        #keyPath(BaseMO.id),
                        mobileLocalId)
                    ) {
                    let editObject = transaction.edit(managedObject)
                    if let identifier = jsonObject["id"] as? String {
                        editObject?.id = identifier
                    }
                }
            }
        }
    }

    let managedObjects = try! transaction.importUniqueObjects(
        Into<T>(),
        sourceArray: jsonObjects)

    return managedObjects as! T
}

使用:

let array: [ExerciseEntity] = replaceWorkoutsIdentifiers(from jsonObjects: ..., transaction: ...)

这篇关于Swift泛型函数问题.减少重复代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆