Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 是流量';与这种多态性固有的结构亚型相关的信息丢失?_Javascript_Polymorphism_Flowtype_Subtyping_Structural Typing - Fatal编程技术网

Javascript 是流量';与这种多态性固有的结构亚型相关的信息丢失?

Javascript 是流量';与这种多态性固有的结构亚型相关的信息丢失?,javascript,polymorphism,flowtype,subtyping,structural-typing,Javascript,Polymorphism,Flowtype,Subtyping,Structural Typing,流程中的结构子类型可能导致信息丢失: type O = {x: number, y: number}; type P = {x: number, y: number, z: number} function f(o: O) { return o.x * 2, o.y * 2, o; } const p: P = {x: 2, y: 3, z: 100}; const r = f(p); r.z // type error (property not found) (这段代码很糟糕

流程中的结构子类型可能导致信息丢失:

type O = {x: number, y: number};
type P = {x: number, y: number, z: number}

function f(o: O) {
    return o.x * 2, o.y * 2, o;
}

const p: P = {x: 2, y: 3, z: 100};
const r = f(p);

r.z // type error (property not found)
(这段代码很糟糕,因为它执行可见的突变。它仅用于说明目的。)

我已经读过,行多态性是一个概念,可以避免这种信息丢失,而不会危及类型安全

有没有一种方法可以实现与子类型多态性相同的效果

[编辑]

为了向更多的听众发表演讲,我对有些可怕的术语做了简要的解释:

  • Polymorpishm只是一个花哨的词,用于确定两种类型是否相等,也就是说,它使刚性类型系统更加灵活
  • 参数多态性(流中的泛型)指出两种类型总是等价的,因为类型根本不重要
  • 子类型多态性(流中的子类型)表示,如果可以从两种类型派生层次结构,则这两种类型是等效的,即将子类型包含在其子类型下
  • 行多态性类似于子类型,但解决了信息丢失问题(但从技术上讲,不再存在子类型关系,因此它不是子类型的一种形式)
  • 有界多态性表示两种类型仅在特定目的下是等效的,例如相等、顺序、映射等

关于Flowtype,我非常确定您的功能是问题所在

如果您改为这样做:

function f<T: O>(o: T): T {
  o.x *= 2;
  o.y *= 2;
  return o;
}

r.z; // okay
函数指定它显式查找O类型的对象,而不是O类型的对象或允许O的子类型。在OPs函数中,我们将参数o向下转换为类型o,而不是使用泛型(这很糟糕)。处理此问题的正确方法是利用泛型指定它可以是O类型或O的子类型,具体操作如下:

function f<T: O> (o: T): T {
  o.x *= 2;
  o.y *= 2;
  return o;
}
函数f(o:T):T{ o、 x*=2; o、 y*=2; 返回o; } 以及它与函数参数、对象等的关系

有关部分是:

  • 泛型允许您在添加约束时保留更具体的类型。这样,泛型上的类型充当“边界”

  • 泛型有时允许您将类似参数的类型传递给函数。这些被称为参数化泛型(或参数多态性)。”


为什么我的函数是个问题?它只是依赖于子类型的承诺,即人们可以将子类型传递到任何需要它的父类型的地方。你的建议是使用有界多态性。这只是意味着子类型不如其他形式的多态性——至少在某些情况下,在实现子类型所需的复杂性方面是如此一个可靠的算法。@f或者我理解你说的,它看起来应该可以工作,但是对于你的函数,你说它显式地寻找一个O类型的参数,而不是O类型的参数或O的子类型。指定这个参数是,你告诉编译器你期望的是一个O类型的参数O或子类型O。检查Java如何处理它@ftor检查我的更新答案,因为它更好地解释了我以前的评论和OOP,但在flow的上下文中。+1感谢你的努力。我认为决定性的线索实际上是在你的一条评论中。这是子类型。这是一个OO概念,我试图从FP的角度来判断它。就我个人而言,这种隐式向下转换似乎是类型系统的子类型部分中的一个错误。您展示了一种更可靠的替代方法,我将其称为结构类型的有界泛型。这种多态性对我来说比结构子类型更有意义。我同意它的功能似乎有点奇怪,您可能会rgue认为这可能会被视为一个bug。当您执行隐式向下转换时,编译器可能会警告您,因为我觉得编码标准应该鼓励人们不要这样做。此外,我觉得隐式向下转换在调试时会导致很多混乱,正如我们通过您的示例所看到的。我没有看到任何错误编译器的问题只是警告用户,但仍然成功编译程序。
function f<T: O> (o: T): T {
  o.x *= 2;
  o.y *= 2;
  return o;
}