简体   繁体   English

Swift 中一个数组中的不同结构

[英]Different structs in one array in Swift

I have a struct called trip .我有一个名为trip的结构。

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

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

As you can see, there is an array inside.可以看到,里面有一个数组。 I'm adding some other structs like element_flight into this array by function addItemtoElements .我正在通过函数addItemtoElements添加一些其他结构,如element_flight到这个数组中。

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

Then I'm trying to create a list using table view:然后我尝试使用表视图创建一个列表:

    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
}

I can't get any of parts of struct (like origin in code).我无法获得结构的任何部分(例如代码中的origin )。 What am I doing wrong?我做错了什么?

I'm creating similar structs to element_flight and it could be the best way to put it in one array and then show in table view.我正在创建与element_flight类似的结构,这可能是将它放在一个数组中然后在表视图中显示的最佳方式。

A simple, naive solution would be to cast elem to the correct type:一个简单、天真的解决方案是将elem转换为正确的类型:

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

However, since the elements array can store Any , what if elem is some other type?但是,由于elements数组可以存储Any ,如果elem是其他类型怎么办? Obviously, it will crash!显然,它会崩溃!

I don't understand why you want to store a bunch of Any in elements .我不明白你为什么要在elements存储一堆Any This is a sign or bad code.这是一个标志或错误的代码。 Any is seldom used in Swift. Any在 Swift 中很少使用。

If you're just going to store some types, but not Any types, in elements , create a protocol and make all the types that you want to store conform to it.如果您只是打算在elements存储某些类型,而不是Any类型,请创建一个协议并使您要存储的所有类型都符合它。 At least you get a little bit of type safety.至少你会得到一点类型安全。

Let's say your array will only contain two structs: element_flight and SomeOtherStruct .假设您的数组将只包含两个结构: element_flightSomeOtherStruct You should do something like this:你应该做这样的事情:

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

And change the array to be of type [SomeProtocol] .并将数组更改为[SomeProtocol]类型。

Now in the cellForRowAtIndexPath method, you need to test whether elem is element_flight or SomeOtherStruct :现在在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
}

You should cast them to FlightInfo (use this name instead of element_flight - type name in Swift should be written in CamelCase).您应该将它们转换为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
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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