Flow 数组的多态性和子类型
Polymorphism and subtypes for Flow arrays
我无法像在 Java 等另一种语言中那样使用 Flow 泛型在数组中使用多态子类型。
考虑以下因素。
interface Person {
name:string;
}
class Employee implements Person {
name:string;
badge:string;
}
interface Workplace {
people:Array<Person>;
}
class MyOffice implements Workplace {
people:Array<Employee>; // ERROR: Incompatible with Workplace.people
}
这在 Java 中也会失败;但是 Java 有一种方法可以通过指示 Workplace
中的 people
数组将包含 Person
.
的子类型来正确实现这一点
interface Workplace {
people:Array<? extends Person>; // PSUEDO CODE: This is how Java supports subtypes
}
我没能在 Flow 中找到类似的机制。 Flow 在这里讨论方差:https://flow.org/en/docs/lang/variance/#toc-covariance and https://flow.org/en/docs/lang/depth-subtyping/
这表明以下应该有效。
interface Workplace {
people:Array<+Person>;
}
但是这个语法失败了。
在 Flow 中有声明数组协变类型的方法吗?
Flow 的变化需要一些时间来适应。正如您所提到的,核心的是如果
这两个操作将无效
interface Workplace {
people:Array<Person>;
}
按原样被允许:
var workplace: Workplace = new MyOffice();
// Not an `Employee`, can't allow adding to array
workplace.people.push(new SomeOtherPersonImpl());
// Not an `Employee`, can't allow replacing array.
workplace.people = [new SomeOtherPersonImpl()];
要获得这两个属性,我们需要
- 将
people
数组设为只读 ($ReadOnlyArray)。
- 将
people
属性 设为只读。 (你提到的+
)
结合这些,你最终得到:
interface Workplace {
+people: $ReadOnlyArray<Person>;
}
我无法像在 Java 等另一种语言中那样使用 Flow 泛型在数组中使用多态子类型。
考虑以下因素。
interface Person {
name:string;
}
class Employee implements Person {
name:string;
badge:string;
}
interface Workplace {
people:Array<Person>;
}
class MyOffice implements Workplace {
people:Array<Employee>; // ERROR: Incompatible with Workplace.people
}
这在 Java 中也会失败;但是 Java 有一种方法可以通过指示 Workplace
中的 people
数组将包含 Person
.
interface Workplace {
people:Array<? extends Person>; // PSUEDO CODE: This is how Java supports subtypes
}
我没能在 Flow 中找到类似的机制。 Flow 在这里讨论方差:https://flow.org/en/docs/lang/variance/#toc-covariance and https://flow.org/en/docs/lang/depth-subtyping/
这表明以下应该有效。
interface Workplace {
people:Array<+Person>;
}
但是这个语法失败了。
在 Flow 中有声明数组协变类型的方法吗?
Flow 的变化需要一些时间来适应。正如您所提到的,核心的是如果
这两个操作将无效interface Workplace {
people:Array<Person>;
}
按原样被允许:
var workplace: Workplace = new MyOffice();
// Not an `Employee`, can't allow adding to array
workplace.people.push(new SomeOtherPersonImpl());
// Not an `Employee`, can't allow replacing array.
workplace.people = [new SomeOtherPersonImpl()];
要获得这两个属性,我们需要
- 将
people
数组设为只读 ($ReadOnlyArray)。 - 将
people
属性 设为只读。 (你提到的+
)
结合这些,你最终得到:
interface Workplace {
+people: $ReadOnlyArray<Person>;
}