Reputation: 534
I have a swift struct named Product which takes a Dictionary in its init method. I want to compute a price value
in a local Price struct within my Product. I want this value to be a let
constant since it won't ever change, but swift won't allow me to do that without using var
, saying that the let
constant is not properly initialized.
How can I make my value
property inside my Price struct a let constant in this case?
struct Product {
let price: Price
init(dictionary: Dictionary<String, AnyObject>) {
if let tmp = dictionary["price"] as? Dictionary<String, AnyObject> { price = Price(dictionary: tmp) } else { price = Price() }
}
struct Price {
var value = ""
init() {
}
init(dictionary: Dictionary<String, AnyObject>) {
if let xForY = dictionary["xForY"] as? Array<Int> {
if xForY.count == 2 {
value = "\(xForY[0]) for \(xForY[1])"
}
}
if let xForPrice = dictionary["xForPrice"] as? Array<Int> {
if value == "" && xForPrice.count == 2 {
value = "\(xForPrice[0]) / \(xForPrice[1]):-"
}
}
if let reduced = dictionary["reduced"] as? String {
if value == "" {
value = "\(reduced):-"
}
}
}
}
}
Upvotes: 0
Views: 995
Reputation: 1300
You have to rewrite the code so that the compiler gets what you intend to do actually. It is not clever enough to deduce it from the way you coded it.
I would also suggest that you make the initializer for the Price
struct failable instead of using an empty string for the value
property. As a consequence of that change the price
property of the Product
struct becomes an optional.
struct Product {
let price: Price?
init(dictionary: Dictionary<String, AnyObject>) {
if let tmp = dictionary["price"] as? Dictionary<String, AnyObject> {
price = Price(dictionary: tmp)
}
else {
price = nil
}
}
struct Price {
let value : String
init?(dictionary: Dictionary<String, AnyObject>) {
if let xForY = dictionary["xForY"] as? Array<Int> where xForY.count == 2 {
value = "\(xForY[0]) for \(xForY[1])"
}
else if let xForPrice = dictionary["xForPrice"] as? Array<Int> where xForPrice.count == 2 {
value = "\(xForPrice[0]) / \(xForPrice[1]):-"
}
else if let reduced = dictionary["reduced"] as? String {
value = "\(reduced):-"
}
else {
return nil
}
}
}
}
Upvotes: 2
Reputation: 469
The trouble is that (1) you're assigning to value
in the declaration, (2) you're not assigning a value in init()
, and (3) you're referencing and reassigning value
in init([String: AnyObject])
. You can only assign a value to a constant once and can only reference its value after its been assigned to.
To fix the issue, you can either make your property publicly readonly:
private(set) var value: String = ""
Or you can use a second variable inside your init
:
struct Price {
let value: String
init() {
self.value = ""
}
init(dictionary: Dictionary<String, AnyObject>) {
var v: String = ""
if let xForY = dictionary["xForY"] as? Array<Int> {
if xForY.count == 2 {
v = "\(xForY[0]) for \(xForY[1])"
}
}
if let xForPrice = dictionary["xForPrice"] as? Array<Int> {
if v == "" && xForPrice.count == 2 {
v = "\(xForPrice[0]) / \(xForPrice[1]):-"
}
}
if let reduced = dictionary["reduced"] as? String {
if v == "" {
v = "\(reduced):-"
}
}
self.value = v
}
}
Upvotes: 1