【问题标题】:Different structs in one array in SwiftSwift 中一个数组中的不同结构
【发布时间】:2016-07-17 00:21:57
【问题描述】:

我有一个名为 trip 的结构。

struct trip {
    var name: String
    var description: String
    var elements: [Any] = []

    mutating func addItemToElements(newValue: Any) {
       elements.append(newValue)
    }
}

如你所见,里面有一个数组。我正在通过函数addItemtoElements 将一些其他结构(如element_flight)添加到此数组中。

struct element_flight {
    var origin: String
    var destination: String
    var flightno: String
    var departure: NSDate
    var arrival: NSDate
    var seat: String
}

然后我尝试使用表格视图创建一个列表:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "elementTrip", for: indexPath) as! CellInElementsOfTripsTableViewCell
    let elem = trips[0].elements[indexPath.row]
    cell.mainTextLabel.text = elem.origin //it doesn't work

    return cell
}

我无法获取 struct 的任何部分(例如代码中的 origin)。我做错了什么?

我正在创建与element_flight 类似的结构,这可能是将其放在一个数组中然后在表格视图中显示的最佳方式。

【问题讨论】:

  • Try cast 将它们转换为正确的类型或存储它们是什么类型并将它们正确地转换为具体类型。现在,编译器只知道elemAny 类型,在线:let elem = trips[0].elements[indexPath.row]

标签: ios arrays swift xcode struct


【解决方案1】:

一个简单、天真的解决方案是将elem 转换为正确的类型:

cell.mainTextLabel.text = (elem as! element_flight).origin

但是,既然elements 数组可以存储Any,那么如果elem 是其他类型呢?很明显,它会崩溃!

我不明白你为什么要在elements 中存储一堆Any。这是一个标志或错误代码。 Any 在 Swift 中很少使用。

如果您只是要存储 一些 类型,而不是 Any 类型,请在 elements 中创建一个协议,并使您要存储的所有类型都符合它。至少你得到一点类型安全。

假设您的数组将只包含两个结构:element_flightSomeOtherStruct。你应该这样做:

protocol SomeProtocol { // please give this a proper name yourself
    // properties/methods that are common among element_flight and SomOtherStruct
}

struct element_flight: SomeProtocol {
    // ...
}

struct SomeOtherStruct: SomeProtocol {
    // ...
}

并将数组更改为 [SomeProtocol] 类型。

现在在cellForRowAtIndexPath方法中,需要测试elemelement_flight还是SomeOtherStruct

if let flight = elem as? element_flight {
    cell.mainTextLabel.text = flight.origin
} else if let someOtherStuff = elem as? SomeOtherStruct {
    // do some other stuff
} else {
    // something's wrong if this is executed, maybe call fatalError
}

【讨论】:

  • 这非常有用,现在它就像一个魅力。谢谢!
【解决方案2】:

您应该将它们转换为 FlightInfo(使用此名称而不是 element_flight - Swift 中的类型名称应该用 CamelCase 编写)。

override func tableView(_ tableView: UITableView, 
           cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: "elementTrip", 
                     for: indexPath) as! CellInElementsOfTripsTableViewCell

  if let flightInfo = trips[0].elements[indexPath.row] as? FlightInfo {
    cell.mainTextLabel.text = flightInfo.origin //it doesn't work
  }

  return cell
}

【讨论】:

  • 其实FlightInfoPascalCase中。
【解决方案3】:

另一种方法是将不同的结构存储在Any 数组中,并使用is 变量来测试类型,然后再将其复制到变量中。

【讨论】:

    猜你喜欢
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 2016-01-21
    • 2020-04-07
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多