`mixed` 和 `any` 有啥区别?
Posted
技术标签:
【中文标题】`mixed` 和 `any` 有啥区别?【英文标题】:What is the difference between `mixed` and `any`?`mixed` 和 `any` 有什么区别? 【发布时间】:2015-07-12 07:26:36 【问题描述】:docs 说:
mixed
:所有类型的“超类型”。任何类型都可以流入mixed
。any
:“动态”类型。任何类型都可以流入any
,反之亦然
mixed
和 any
不能互换使用的情况是什么?
【问题讨论】:
该文档链接已损坏,current docs onmixed
没有类似的文本。这是该文档页面存在时的样子:web.archive.org/web/20150513033813/http://flowtype.org/docs/…
【参考方案1】:
区别在于“反之亦然”:any
可以流入其他类型,但 mixed
不能。
/* @flow */
var numeric:number = 0;
var anyTyped:any;
var mixTyped:mixed;
numeric = anyTyped;
numeric = mixTyped; // This will throw a flow check error: "Cannot assign `mixTyped` to `numeric` because mixed is incompatible with number. [incompatible-type]"
来自您链接到的文档:
由于此注释的特殊性质,值得特别指出任何内容。使用 any 来转义 Flow 的静态类型。换句话说,如果 Flow 妨碍了您,并且您完全确信您的程序类型正确,您可以通过使用 any 类型注释错误路径上的位置来消除错误。
【讨论】:
啊,所以你必须这样做looselyTyped = someType; numeric = looselyTyped;
:-)【参考方案2】:
“Any”支持协变和逆变。那是因为“any”是所有类型的超类型和子类型。
因此这是可行的,
let genericVariable: any = 20;
let numericVariable: number;
genericVariable = numericVariable; // No error
numericVariable = genericVariable; // No error
mixed 仅支持协方差。它是超类型,不是所有类型的子类型。
let genericVariable: mixed = 20;
let numericVariable: number;
numericVariable = genericVariable; // This shows error
genericVariable = numericVariable; // This works fine.
协方差 - 通用类型(父)可以被特殊类型(子)替换
逆变 - 特殊类型(子)可以替换为通用类型(父)。这是一个问题,除非受到某些约定的保护。
【讨论】:
【参考方案3】:当 flow 看到 any
时,这意味着您可以使用任何类型。程序对参数的类型不关心,也不会尝试推断结果类型。所以结果类型也将是any
。
例如下面的代码不会报任何错误:
// @flow
function add(one: any, two: any): number
return one + two;
add(1, 2); // Works.
add("1", "2"); // Works.
add(, []); // Works.
但应该以某种方式处理“混合”类型以推断实际类型。
// @flow
function stringify(value: mixed)
// $ExpectError
return "" + value; // Error!
stringify("foo");
相反,您必须通过优化它来确保该值是某种类型。
// @flow
function stringify(value: mixed)
if (typeof value === 'string')
return "" + value; // Works!
else
return "";
stringify("foo");
【讨论】:
以上是关于`mixed` 和 `any` 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
git reset --mixed、--soft 和 --hard 有啥区别?
Mockito Matchers isA、any、eq 和 same 有啥区别?
Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有啥区别?