简体   繁体   中英

Why this struct with optional values returns nothing?

I visited this thread to know about optionals and I saw a quote from the docs, which I quote again.

If your custom type has a stored property that is logically allowed to have “no value”—perhaps because its value cannot be set during initialization, or because it is allowed to have “no value” at some later point—declare the property with an optional type. Properties of optional type are automatically initialized with a value of nil, indicating that the property is deliberately intended to have “no value yet” during initialization.

So I have the same condition. I have some variables that may have some values or not. So here's my struct

struct Notification {
    var type : String?
    var dp : String?
    var name : String?
    var postImage : String?
    var whomenc : String?
}

So I'm trying to create a struct array but whenever the struct is initialized, I get nothing in return

obj.forEach {
    guard let type = $0["type"] as? String else {return}
    print("type = \(type)")
    guard let dp = $0["dp"] as? String else {return}
    print("dp = \(dp)")
    guard let name = $0["name"] as? String else {return}
    print("name = \(name)")
    guard let postimg = $0["postimg"] as? String else {return}
    print("postimg = \(postimg)")
    guard let whomenc:String = $0["whomenc"] as? String else {return}
    print("whomenc = \(whomenc)")
    let notification = Notification(type: type, dp: dp, name: name, postImage: postimg, whomenc: whomenc)
    self.notifiArray.append(notification)
    print("notifiArray.count = \(self.notifiArray.count)") // this satement doesn't gets executed.
}

And this is what I get in the log

type = commentCommented
dp = default.jpg
name = testt
postimg = 69663rocketleague32bitdx914102018180636.mp4
type = commentCommented
dp = default.jpg
name = testt
postimg = 69663rocketleague32bitdx914102018180636.mp4
type = followed
dp = default.jpg
name = bott1
type = followed
dp = default.jpg
name = bott2

I tried printing the notification variable and it is empty. I tried printing the notifiArray which returns as []

The array is declared as

var notifiArray = [Notification]()

Any idea why this behavior?

This statement is not succeeding:

guard let whomenc:String = $0["whomenc"] as? String else {return}

either because the key "whomenc" doesn't exist or the type isn't a String . The guard statement then return s from the closure and does nothing more for that dictionary.

Since you can create a Notification even if some values are nil , you could remove the guard statements and pass the (possibly nil ) values to the Notification initializer:

obj.forEach {
    let type = $0["type"] as? String
    print("type = \(type ?? "nil")")
    let dp = $0["dp"] as? String
    print("dp = \(dp ?? "nil")")
    let name = $0["name"] as? String
    print("name = \(name ?? "nil")")
    let postimg = $0["postimg"] as? String
    print("postimg = \(postimg ?? "nil")")
    let whomenc = $0["whomenc"] as? String
    print("whomenc = \(whomenc ?? "nil")")
    let notification = Notification(type: type, dp: dp, name: name, postImage: postimg, whomenc: whomenc)
    self.notifiArray.append(notification)
    print("notifiArray.count = \(self.notifiArray.count)") // this satement doesn't gets executed.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM