So it's going to be hard to do exactly what you're trying to do here, because by putting all your plugs into an array, you will necessarily lose information about what each plug's particular dataType is. And that means when you get to this line:
plugs[3].value[0] + plugs[2].value
the compiler has no way of knowing what type plugs[3].value[0] and plugs[2].value are. For instance, for all the compiler knows, plugs[2].value is could be a String and plugs[3].value[0] could be a UInt32.
So the quick-and-dirty answer to this is, if you want to preserve type information in a group of objects, you could use a tuple:
let plugs = (
plug1,
plug2,
plug3,
doublePlg,
intListPlg
)
plugs.3.value[0] + plugs.2.value
This will allow the compiler to know at build time exactly what the value of each of the plugs are.
If the list has to be dynamic, you could also cast the plugs as they come out of your array:
var plugs: [Any] = []
...
// check if each plug is the type you expect at runtime
if let plug3 = plugs[3] as? Plug<[Double]>, let plug2 = plugs[2] as? Plug<Double> {
plug3.value[0] + plug2.value
}
But converting things to Any and then casting them back to specific types has a bit of code-smell in Swift.
A better solution would probably be that, if you have something consistent you have to do with each of these plugs, put that inside a protocol without an associated type constraint, and then you can use an array of [GenericPlug] without issues.