【问题标题】:Getting value in a nested wrapped variable in Swift在 Swift 中的嵌套包装变量中获取值
【发布时间】:2016-09-22 07:44:28
【问题描述】:

目前,我需要这段代码来让我的数据显示在 UITableViewCell 标签上:

guard let leaseUnits = Data.leaseUnits else { return cell; }
guard let leaseUnit = leaseUnits[indexPath.row] else { return cell; }
guard let unitId = leaseUnit.unitId else { return cell; }    
guard let units = Data.units else { return cell; }
guard let unit = units[unitId] else { return cell; }
(cell.viewWithTag(1)! as! UILabel).text = unit.unitNumber;

或者我可以这样做,但有空运行时错误的风险:

let unitNumber = Data.units![Data.leaseUnits![indexPath.row]!.unitId]!.unitNumber;
(cell.viewWithTag(1)! as! UILabel).text = unitNumber; 

有什么办法可以让它变成这样:

let unitNumber = Data.units?[Data.leaseUnits?[indexPath.row]?.unitId]?.unitNumber;
if (unitNumber != nil) { (cell.viewWithTag(1)! as! UILabel).text = unitNumber!; }

我只想得到一个值,如果任何链数据检索为 nil,则只为整个操作返回一个 nil。

编辑:

好的,从 dfri 的评论来看:我至少可以像这样简化它:

if let unitId = Data.leaseUnits?[indexPath.row]?.unitId {
    if let unitNumber = Data.units?[unitId]?.unitNumber {
        (cell.viewWithTag(1)! as! UILabel).text = unitNumber;
    }
}

没有比这更简单的了。

我想这已经足够了。现在我更了解了可选链的局限性。

编辑 2:

所以最后可以变成这样,去掉一个嵌套块:

if let unitId = Data.leaseUnits?[indexPath.row]?.unitId, 
    let unitNumber = Data.units?[unitId]?.unitNumber {
    (cell.viewWithTag(1)! as! UILabel).text = unitNumber;
}

IMO,dfri 应该将他的评论作为答案,以便我接受。 :)

【问题讨论】:

  • 查看可选链接(if let a?.b?.c { ... } 其中abc 都是可选的)。
  • @dfri 等等,这仅在 Swift 3 上可用吗?
  • 可选链接至少从 Swift 2 开始就已经存在(当我加入火车时),甚至可能更长。请参阅the e.g. post in it on the SO doc. page for Swift,或参考官方语言指南。
  • 所以你的意思是我这样做:if let unitNumber = Data.units?[Data.leaseUnits?[indexPath.row]?.unitId]?.unitNumber { do something }?
  • 请注意,您不需要嵌套两个可选绑定子句,但可以将它们作为两个逗号分隔的可选绑定放在同一个 if 语句 (if let foo = a?.b?.c, let bar = bax[foo] { ... }) 中,其中第一个绑定属性(如果成功)可在以下之一中找到。

标签: ios swift null forced-unwrapping


【解决方案1】:

您可以使用可选链接,如the Language Guide - Optional Chaining中所述

struct Bar {
    let baz: Int?
    init(baz: Int) { self.baz = baz }
}

struct Foo {
    let bar: Bar?
    init(bar: Bar) { self.bar = bar }
}

let bar: Bar? = Bar(baz: 42)
let foo: Foo? = Foo(bar: bar!)

if let innerBaz = foo?.bar?.baz { 
    print(innerBaz) // 42
}

另外,请注意,您不需要嵌套两个可选绑定子句(有两个嵌套的 if 语句),但可以将它们作为两个(或更多)逗号分隔的可选绑定放在同一个 if 语句中,其中第一个绑定的属性(如果成功)在以下一个中可用。

/* ... as example above */

let dict = [42: "foobar!"]

if let innerBaz = foo?.bar?.baz, let dictValue = dict[innerBaz] { 
    print(dictValue) // foobar!
}

【讨论】:

    猜你喜欢
    • 2020-12-09
    • 2021-02-24
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多