在转换对象 Swift 中设置值

Posted

技术标签:

【中文标题】在转换对象 Swift 中设置值【英文标题】:Set values in a casted object Swift 【发布时间】:2019-11-08 15:50:48 【问题描述】:

我有一个协议Food,其中包含名称和价格。

结构体Fruit 正在实现这个协议,并有另一个名为color 的特定变量。

一个类Fridge(我的ViewController)可以包含每一种食物,所以变量food的数据类型是Food

在第一步中,我将food 变量设置为一个新的Fruit

fridge.food = Fruit(name: "Apple", price: 0.99, color: "Yellow")

然后在我的 VC Fridge 中,我想用以下代码修改水果颜色:

var fruit = fridge.food as! Fruit
fruit.color = "Red"

稍后,当我想检索它返回“黄色”的信息时:

var fruit = fridge.food as! Fruit
print(fruit.color)
//prints Yellow

现在的问题是如何正确更改该castet 对象的值?

【问题讨论】:

你确定这些是类而不是结构吗? 使用带有vars 的结构或类,它按预期工作。是否存在您可能正在重新分配或可能不会触发更改的地方? 【参考方案1】:

当前代码如下所示。

protocol Food 
    var name : String set get
    var price : Double set get


struct Fruit : Food 
    var name : String
    var price : Double
    var color : String


class Fridge 
    var food : Fruit
    init(food : Fruit) 
       self.food = food
    


class Container 
    var food : Fruit
    init(food : Fruit) 
        self.food = food
    



var container = Container.init(food: Fruit(name: "Apple", price: 0.99, color: "Yellow"))
var fridge = Fridge.init(food:container.food)
var fruit = fridge.food as! Fruit
fruit.color = "Red"
print(fruit.color) // "Red"

var fruit1 = fridge.food as! Fruit
print(fruit1.color) // "Yellow"

因为 Fruit 是 struct 类型,而 struct 是值类型而不是引用类型

var fruit = fridge.food as! Fruit // it will create a new reference instead of modified the created one.
fruit.color = "Red" 
print(fruit.color) //"Red"

解决方案:

var fridge = Fridge.init(food: container.food)
fridge.food.color = "Red"
print(fridge.food.color) // "Red"

【讨论】:

@JoakimDanielson 如果他们是类,那么这是不可能的。打印黄色而不是红色 是的,它确实看起来很奇怪 我检查了你的答案,但 Fridgefood 的数据类型是 Food 而不是 Fruit。 (为了更清楚,我还更新了我的问题)。 still food是Fruit not Fridge的类型,fridge.food = Fruit(name: "Apple", price: 0.99, color: "Yellow"),先纠正你的问题【参考方案2】:
class Fruit
    var name:String
    var price: Double
    var color:String
    init(name:String,price:Double,color:String) 
        self.name = name
        self.price = price
        self.color = color
    

然后

override func viewDidLoad() 
    super.viewDidLoad()
    let fruit = Fruit(name: "Apple", price: 0.99, color: "Yellow")
    print(fruit.color)// Prints Yellow
    fruit.color = "RED"
    print(fruit.color) //Prints RED

【讨论】:

您在这里错过了问题的核心部分,即通过冰箱对象访问水果对象。我确信 OP 知道如何更改属性 ;) 我认为这与您的答案无关。【参考方案3】:

你总是必须使用 optional as? 进行强制转换,否则你会在其他类型的情况下崩溃。

这是正确的做法:

protocol Food 
    var name : String set get
    var price : Double set get


struct Fruit : Food 
    var name : String
    var price : Double
    var color : String


class Fridge 
    var food : Food
    init(food : Fruit) 
       self.food = food
    



var fridge = Fridge.init(food: Fruit(name: "Apple", price: 0.99, color: "Yellow"))

print(fridge.food.name) // "Apple"
if let food = fridge.food as? Fruit 
    print(food.color) // "Yellow"


if var fruit = fridge.food as? Fruit 
    fruit.color = "Red"
    fridge.food = fruit

if let food = fridge.food as? Fruit 
    print(food.color) // "Red"

【讨论】:

以上是关于在转换对象 Swift 中设置值的主要内容,如果未能解决你的问题,请参考以下文章

在对象中设置值时 Redux 数据不重新呈现(Immutable.js)

无法在 LiveData 中设置值

是否可以在没有设置器的情况下在属性中设置值?

如何使用淘汰赛从复杂对象的选择选项中设置值?

如何在钩子中设置值

在 NSArray 中设置值