I have the struct Vector:
struct Vector{
var X : Measurement<Dimension>
var Y : Measurement<Dimension>
var Z : Measurement<Dimension>
...
And I create new object, for example:
let test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>
var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))
Everything works fine. But if try to use variable from other class, I got the error: "Cannot convert value of type 'Measurement' to type 'Measurement' in coercion"
final class SettingsManager{
...
var test = Measurement(value: 1.5, unit: UnitLength.inches)
... }
class Calculator {
...
let test = SettingsManager.shared.test as Measurement<Dimension>
var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))
I tried "as!" and got
Cast from 'Measurement<UnitLength>'
to unrelated type 'Measurement<Dimension>'
always fails
The same variable declared in this class works fine as I showed above. What I did wrong?
CodePudding user response:
Use
var test : Measurement<Dimension> = Measurement(value: 1.5, unit: UnitLength.inches)
CodePudding user response:
A Measurement<UnitLength> is not a kind of Measurement<Dimension>. These are unrelated types. It only works here:
let test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>
var lVector = Vector(x: Measurement(value: 10, unit: UnitLength.meters), y: test, z: Measurement(value: 10, unit: UnitLength.meters))
because the Measurement(...) calls here are actually creating Measurement<Dimension>s, since that is what is being expected at the callsite. as Measurement<Dimension> tells it that you want a Measurement<Dimension>, and the parameter type of x and z are also Measurement<Dimension>. The type inference algorithm is smart enough to see that you must also mean Measurement<Dimension>(...).
Measurement<Dimension>.init takes a Dimension as its second parameter, and UnitLength is a subtype of that, so no problems there.
On the other hand, in SettingsManager, you declared test like this:
var test = Measurement(value: 1.5, unit: UnitLength.inches)
Nowhere here did you mention Measurement<Dimension>, so the type inference algorithm just uses the second parameter to infer that you must mean Measurement<UnitLength>, and so the type of test is Measurement<UnitLength>.
If you just add as Measurement<Dimension>
var test = Measurement(value: 1.5, unit: UnitLength.inches) as Measurement<Dimension>
it should work.
However, wouldn't it make more sense to for all three components of the vector to have the same type of unit?
struct Vector<T: Dimension>{
var X : Measurement<T>
var Y : Measurement<T>
var Z : Measurement<T>
}
