【问题标题】:Why this struct with optional values returns nothing?为什么这个带有可选值的结构什么都不返回?
【发布时间】:2019-09-08 15:19:33
【问题描述】:

我访问了this thread 以了解可选选项,我看到了来自文档的引用,我再次引用。

如果您的自定义类型有一个逻辑上允许“无值”的存储属性——可能是因为它的值不能在初始化期间设置,或者因为它允许在稍后的某个时间点有“无值”——声明具有可选类型的属性。可选类型的属性会自动使用 nil 值进行初始化,这表明该属性在初始化期间故意设置为“还没有值”。

所以我也有同样的情况。我有一些变量可能有一些值或没有。所以这是我的结构

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

所以我正在尝试创建一个结构数组,但是无论何时初始化结构,我都没有得到任何回报

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.
}

这就是我在日志中得到的内容

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

我尝试打印通知变量,但它是空的。我尝试打印返回为[]

的notifiArray

数组声明为

var notifiArray = [Notification]()

知道为什么会出现这种行为吗?

【问题讨论】:

  • 您可以真的通过将 Notification 初始化逻辑提取到 ... Notification 初始化程序中来大量清理此代码。你应该使用map 而不是forEach + append
  • @Alexander 我不明白。另外,我不想返回任何东西,为什么要使用 .map?
  • 1) 你可以在你的 Notification 类型上创建一个新的初始化器,它接受一个字典,并封装所有从字典初始化 Notification 的逻辑。 2) 您试图获取一个数组 (obj) 的元素,以某种方式转换它们(使用这些元素初始化新的 Notification 实例),然后生成一个新的结果数组。该操作有一个名称,它是map

标签: arrays swift struct


【解决方案1】:

此语句不成功:

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

要么是因为键 "whomenc" 不存在,要么类型不是 Stringguard 语句然后是 returns 来自闭包,并且对该字典没有任何作用。

由于即使某些值是nil,您也可以创建Notification,因此您可以删除guard 语句并将(可能是nil)值传递给Notification 初始化程序:

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.
}

【讨论】:

  • 那么,为什么我在控制台中没有任何关于此的错误或警告?或者我不应该期待一个,因为我使用了一个保护声明?
  • 就 Swift 而言,这里没有错误或警告。它只是在执行你的代码。你用guard 声明说,如果字典中没有值或者它不是String,那么return 来自闭包,并且对此元素不做任何事情。
  • @weegee Swift 有明确的初始化分析,这是一个编译器步骤,用于验证结构/类的所有变量在初始化程序完成之前是否已初始化。那会发现这个错误。但是,通过将所有字段设为可选,并且不使用自己的初始化程序来设置变量,您自愿放弃了对 Swift 明确初始化保证的访问权限。
猜你喜欢
  • 2016-06-28
  • 1970-01-01
  • 2012-02-16
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多