流类型:"optional function parameters" 和 "maybe types" 之间的差异
Flow Type: difference between "optional function parameters" and "maybe types"
有人可以解释一下 "optional function parameters" 和 "maybe types" 之间的区别吗?
定义听起来很相似:
可能类型: "Maybe types are for places where a value is optional"
可选函数参数: "Functions can have optional parameters where a question mark ? comes after the parameter name."
我从语法的角度理解差异。但是,听起来两者都可以用于您想要为函数定义 可选参数 的情况。你会在哪里使用一个而不是另一个?
没有区别。但它们也是完全不同的东西。
我认为这里有些概念上的混乱。这是可选参数的示例:
function recase(str, lower) {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', true)
// "test"
recase('test')
// "TEST"
recase()
// Uncaught TypeError: Cannot read property 'toUpperCase' of undefined
我们的函数有两个参数。第一个是必需的,如果我们不传递至少一个参数,该函数将抛出异常。第二个是可选的,如果我们不传递第二个则不会抛出异常,返回的值会不同。
请注意,我没有介绍任何类型。这是因为这里的 "optional parameter" 只是一个通用的编程概念。 Flow 没有一些称为 "optional parameters." 的内在特性,Flow 提供的是一种 type 可选参数的方法,称为 "maybe types."
假设我想在上面输入我的函数。嗯,第一遍可能是这样的:
// We're taking a string and a boolean and returning a string, right?
function recase(str: string, lower: boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', false)
// "TEST"
recase('Test', true)
// "test"
recase('Test')
// ^ Cannot call `recase` because function [1] requires another argument.
由于我们将 lower
键入为 boolean
,flow 期望将 boolean
作为第二个参数传递。当我们不传递布尔值时,流程会抛出错误。我们的参数不再是可选的。我们可以 从 lower
中删除 类型,但是 flow 将默认 lower
为 any
类型,这意味着用户可以传递他们想要的任何内容这使得我们的类型模棱两可且容易出错。这是我们可以做的一件事:
function recase(str: string, lower: void | boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', true)
// "test"
recase('Test')
// "TEST"
在流程中,void
类型仅匹配 undefined
的值。如果我们在调用 recase
时没有为 lower
提供值,那么 lower
的值将是 undefined
,通过键入 lower as void | boolean
我们有告诉流 lower
可以是 boolean
或 undefined
(未指定为参数)。
很明显,这是一个非常常见的场景。事实上如此普遍,以至于在某些时候我们可能会考虑封装它。这可以用泛型来完成,像这样:
// Let's call this Q for "Question" but it's nice and short
type Q<T> = void | null | T;
function recase(str: string, lower: Q<boolean>): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
请注意,我们已将 null
添加到我们的通用类型中,因为 undefined
情况与希望能够传入 [=31] 的 null
情况重叠太多=] 可选参数。
好吧,这很常见,以至于流为我们提供了相当于这种情况的语法糖,称为 "maybe types." 如果您能够将我们的 Q
类型重命名为 ?
那么你基本上可能会有类型。
function recase(str: string, lower: ?boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
有人可以解释一下 "optional function parameters" 和 "maybe types" 之间的区别吗?
定义听起来很相似:
可能类型: "Maybe types are for places where a value is optional"
可选函数参数: "Functions can have optional parameters where a question mark ? comes after the parameter name."
我从语法的角度理解差异。但是,听起来两者都可以用于您想要为函数定义 可选参数 的情况。你会在哪里使用一个而不是另一个?
没有区别。但它们也是完全不同的东西。
我认为这里有些概念上的混乱。这是可选参数的示例:
function recase(str, lower) {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', true)
// "test"
recase('test')
// "TEST"
recase()
// Uncaught TypeError: Cannot read property 'toUpperCase' of undefined
我们的函数有两个参数。第一个是必需的,如果我们不传递至少一个参数,该函数将抛出异常。第二个是可选的,如果我们不传递第二个则不会抛出异常,返回的值会不同。
请注意,我没有介绍任何类型。这是因为这里的 "optional parameter" 只是一个通用的编程概念。 Flow 没有一些称为 "optional parameters." 的内在特性,Flow 提供的是一种 type 可选参数的方法,称为 "maybe types."
假设我想在上面输入我的函数。嗯,第一遍可能是这样的:
// We're taking a string and a boolean and returning a string, right?
function recase(str: string, lower: boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', false)
// "TEST"
recase('Test', true)
// "test"
recase('Test')
// ^ Cannot call `recase` because function [1] requires another argument.
由于我们将 lower
键入为 boolean
,flow 期望将 boolean
作为第二个参数传递。当我们不传递布尔值时,流程会抛出错误。我们的参数不再是可选的。我们可以 从 lower
中删除 类型,但是 flow 将默认 lower
为 any
类型,这意味着用户可以传递他们想要的任何内容这使得我们的类型模棱两可且容易出错。这是我们可以做的一件事:
function recase(str: string, lower: void | boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
recase('Test', true)
// "test"
recase('Test')
// "TEST"
在流程中,void
类型仅匹配 undefined
的值。如果我们在调用 recase
时没有为 lower
提供值,那么 lower
的值将是 undefined
,通过键入 lower as void | boolean
我们有告诉流 lower
可以是 boolean
或 undefined
(未指定为参数)。
很明显,这是一个非常常见的场景。事实上如此普遍,以至于在某些时候我们可能会考虑封装它。这可以用泛型来完成,像这样:
// Let's call this Q for "Question" but it's nice and short
type Q<T> = void | null | T;
function recase(str: string, lower: Q<boolean>): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}
请注意,我们已将 null
添加到我们的通用类型中,因为 undefined
情况与希望能够传入 [=31] 的 null
情况重叠太多=] 可选参数。
好吧,这很常见,以至于流为我们提供了相当于这种情况的语法糖,称为 "maybe types." 如果您能够将我们的 Q
类型重命名为 ?
那么你基本上可能会有类型。
function recase(str: string, lower: ?boolean): string {
if (lower) {
return str.toLowerCase();
}
return str.toUpperCase();
}