After sanitizing your code a bit:
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]
If I understand what you want is something like this:
// 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")
}
}
That is: you can cast each item in array as given type to get properties specific to the type. This solves the GET problem. Set is more complicated, since you have an array and structs, which is copied when modified. So technically you can change them, but it won't be the same instance. The most simple way to resolve this, is to have a function that returns an array of modified [Pr]
objects, which you can assign back to 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()
But this may not be a good solution if you are dealing with tons of data, lots of copies, etc, etc... So a more specific use case would be needed to make the answer more useful.