繁体   English   中英

如何在 Swift 中创建具有不同属性的混合结构的数组?

[英]How to create an array with mixed structs with different properties in Swift?

我正在尝试创建一个包含多个结构的数组,我已经创建了一个协议来这样做,它允许我获取和设置相似的属性,但当属性不同时不能。 我现在的代码如下:

结构:

struct A: Pr {
poll: String
res: Int
}

struct B: Pr {
poll:String
ont: String
}

协议:

protocol Pr {
   var poll:String { get set }
}

没有初始化的 var 类型:

var field:[Pr]

稍微清理一下代码后:

protocol Pr {
   var poll:String { get set }
}

struct A: Pr {
  var poll: String
  var res: Int
}

struct B: Pr {
  var poll:String
  var ont: String
}

var field: [Pr]

如果我明白你想要的是这样的:

// Just an example to fill array with something for a demo:
let a = A(poll: "pollA", res: 1)
let b = B(poll: "pollB", ont: "ont")

field = [Pr]()
field.append(a)
field.append(b)

// The actual solution
for pr in field {

    print(pr.poll)

    switch pr {
    case let pr as A:
        print(pr.res)
    case let pr as B:
        print(pr.ont)
    default:
        print("no more properties")
    }
}

也就是说:您可以将数组中的每个项目转换为给定类型,以获取特定于该类型的属性。 这解决了GET问题。 Set 更复杂,因为您有一个数组和结构,在修改时会被复制。 所以从技术上讲,你可以改变它们,但它不会是同一个实例。 解决此问题的最简单方法是使用 function 返回一个修改后的[Pr]对象数组,您可以将其分配回field

func modify() -> [Pr] {

    var result = [Pr]()

    for pr in field {

        switch pr {
        case let pr as A:
            let a = A(poll: pr.poll + "changed", res: pr.res + 1)
            result.append(a)
        case let pr as B:
            let b = B(poll: pr.poll + "changed", ont: pr.ont + "changed")
            result.append(b)
        default:
            print("skip")
        }
    }

    return result
}

field = modify()

但是,如果您要处理大量数据、大量副本等,这可能不是一个好的解决方案……因此,需要一个更具体的用例来使答案更有用。

你有两个问题:

  1. 符合Pr协议的结构数组不是AB对象的数组:

  2. Array 和 Struct 类型都是值类型,因此您不能在不复制的情况下将数组中的条目转换为特定的具体类型。

此代码解决了问题 1,但没有解决问题 2:

(field[0] as? A)?.res = 5

除了将 A 和 B 转换为class (引用类型)对象之外,我不确定是否有解决您的问题的方法。 此代码有效:

protocol Pr {
   var poll:String { get set }
}

class A: Pr, CustomStringConvertible {
    var poll: String
    var res: Int
    
    init(poll: String, res: Int) {
        self.poll = poll
        self.res = res
    }
    
    var description: String {
        return ("A(poll: \(poll), res:\(res))")
    }
}

class B: Pr, CustomStringConvertible {
    var poll:String
    var ont: String

    init(poll: String, ont: String) {
        self.poll = poll
        self.ont = ont
    }
    var description: String {
        return ("B(poll: \(poll), ont:\(ont))")
    }
}

var field:[Pr] = [A(poll:"h", res:3), B(poll:"c", ont:"o"),]
field[0].poll = "p"
field[1].poll = "q"

(field[0] as? A)?.res = 5

(field[1] as? B)?.ont = "z"

暂无
暂无

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

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