Установить значения в отлитом объекте Swift - PullRequest
1 голос
/ 08 ноября 2019

У меня есть протокол Food, который содержит имя и цену.

Структура Fruit реализует этот протокол и имеет другую конкретную переменную с именем color.

Aкласс Fridge (мой ViewController) может содержать любой тип пищи, поэтому тип переменной food равен Food.

На первом шаге я установил для переменной food новыйFruit.

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

Затем в моем ВК Fridge я хочу изменить цвет фруктов следующим кодом:

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

Позже, когда я хочу получить информациюон возвращает «Желтый»:

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

Теперь вопрос в том, как правильно изменить значение этого объекта касты?

Ответы [ 3 ]

0 голосов
/ 08 ноября 2019

Текущий код выглядит следующим образом.

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 является типом значения, а не ссылочным типом

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"
0 голосов
/ 09 ноября 2019

Вы всегда должны приводить с дополнительным 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"
}
0 голосов
/ 08 ноября 2019
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
}
...