【问题标题】:Set values in a casted object Swift在转换对象 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 的结构或类,它按预期工作。是否存在您可能正在重新分配或可能不会触发更改的地方?

标签: swift casting save


【解决方案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"
}

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多