在 Swift 中映射符合协议的类型

Posted

技术标签:

【中文标题】在 Swift 中映射符合协议的类型【英文标题】:Mapping in Swift Between Protocol Conforming Types 【发布时间】:2016-07-13 17:04:18 【问题描述】:

我想在任何两个符合相同协议的对象之间进行映射。通过带有签名的函数这样做会很方便:

func mapFrom<T>(objectA: T, to inout objectB: T)

更好的是(对于不可变类型)将它放在以下形式中:

func map<T, U: T>(from source: T) -> U

它可以以某种方式从T 中的值初始化U 对象。

我想通过 Swift Reflection 而不是使用 Objective-C 运行时来做到这一点,但如果这是唯一的方法,我会接受。如果可以在没有反射的情况下以某种方式完成,那将是惊人的,但我不知道如何。

我想这样做的原因是因为我有符合各自协议的可变 Realm 类,并且我想将它们映射到不可变结构类型。

一个例子是:

/**
    The protocol.
 */
protocol Food 
    var name: String  get 
    var weight: Float  get 
    var price: Float  get 


/**
    The mutable Realm class representation.
 */
final class FoodEntity: Object, Food 
    dynamic var name = ""
    dynamic var weight = 0.0
    dynamic var price = 0.0


/**
    The final struct I want to map to from the Realm representation.
 */
struct FoodProduct: Food 
    let name: String
    let weight: Float
    let price: Float

我希望能够拥有一个通用函数或方法,用于将 FoodEntity 映射到 FoodProduct 而无需手动执行以下操作:

FoodProduct(name: entity.name, weight: entity.weight, price: entity.price)

如果可以做到的话,如何做到这一点?

【问题讨论】:

你的问题太混乱了。请编辑。 这可能有助于开始:***.com/a/24069875/3141234 【参考方案1】:

我认为您正在寻找类似的东西。

 func fetchAllFoodProducts() -> [FoodProduct]
    
        var foodProducts : [FoodProduct] = []

        // Fetch From Realm

        let products = realm.objects(FoodEntity.self)

        for product in products
        
            foodProducts.append(FoodProduct(name: product.name, weight: product.weight, price: product.price))
        

        return foodProducts
    

问题是没有通用的方法来做到这一点。因为您必须以某种方式分配nameweightprice 的值。我想这是你能得到的最接近的。

或者你可以这样做。

 func fetchAllFoodProducts() -> [FoodProduct]
    
        var foodProducts : [FoodProduct] = []

        // Fetch From Realm

        let products = realm.objects(FoodEntity.self)

        for product in products
        
           foodProducts.append(FoodProduct(entity: product))
        

        return foodProducts
    

稍微改变你的FoodEntity

 struct FoodProduct: Food 
        let name: String
        let weight: Float
        let price: Float

        init(entity : FoodEntity)
        
            self.name = entity.name
            self.weight = entity.weight
            self.price = entity.price
        
    

【讨论】:

以上是关于在 Swift 中映射符合协议的类型的主要内容,如果未能解决你的问题,请参考以下文章

Swift3:类型“NSObject”不符合协议“URLAuthenticationChallengeSender”

swift 的字符串类型是不是符合收集协议?

Swift SQLite O-R 映射工具类库 swiftydb

《从零开始学Swift》学习笔记(Day 71)——Swift与C/C++混合编程之数据类型映射

符合 Swift 协议的泛型类型

类型“myViewController”不符合 Swift 中的 UIPIckerDataSource 协议