提问人:Matthew Layton 提问时间:11/18/2019 更新时间:11/19/2019 访问量:80
与语言无关 - 函数和构造函数参数中允许的类型
Language Agnostic - Allowable types in function and constructor parameters
问:
大多数(如果不是全部)静态类型语言都允许您为函数或构造函数参数指定单个类型;例如
function foo(x: string) { ... }
foo("hello") // works
foo(123) // error
TypeScript 是 JavaScript 的静态类型超集,但由于 JavaScript 是一种动态类型语言,TypeScript 允许你更加灵活;例如,可以指定多个允许的类型。
function foo(x: string | number) { ... }
foo("hello") // works
foo(123) // works
foo(true) // error
此外,在 TypeScript 中,这允许您仅将泛型类型参数限制为特定类型;例如:
class Foo<T extends number | string> {
constructor(x: T) { ... }
}
new Foo("hello") // works
new Foo(123) // works
new Foo(true) // fails
问题
我喜欢 TypeScript 将泛型类型参数限制为特定类型的能力,但我也希望能够在其他语言(即 C# 和 Kotlin)中做到这一点,但据我所知,这些语言中没有等效的结构来支持这种约束。如何在其他语言中实现这一目标?
注意:我很乐意接受任何语言的答案,而不仅仅是列出的答案。这更多的是关于更高层次的思考和探索可以跨语言应用的其他途径。
答:
在 F# 中,有 Sum/Union 类型。看起来很像 TypeScript 中的内容,但在 F# 中,它们是使用用于匹配的标签定义的。
这允许您具有具有多个相同类型的案例的总和类型。例如:
type ShoeSize =
| EU of double
| UK of double
| US of double
C++ 20 有一个概念,它能够以您想要的方式约束模板参数,等等。这在语言中引入了一些使用各种技术可以近似的东西,在这里描述它们似乎超出了范围。
TypeScript 可以让你更灵活一些;例如,可以指定多个允许的类型。
不,你不能; 是单一类型,称为联合类型。您可以传递 a 或 a,因为它们都是 的子类型。但你也可以通过任何.number | string
number
string
number | string
number | string
类似地,在第二个示例中,不被限制为 either 或 ;它可以是 或 的任何子类型。甚至T
number
string
number | string
number
string
var x = new Foo<123 | "">(123)
其中又是一个完全普通的 TypeScript 类型。123 | ""
Scala 3 将具有联合类型;有人讨论过 Kotlin 的联合类型,但你可以看到团队并不感兴趣。对于 C#,类似。
评论