关于 typescript 里的泛型(Generics),不太理解为什么要这么繁琐?

2020-05-28 14:53:24 +08:00
 find456789

比如这一段代码:

function identity<T>(arg: T): T {
    return arg;
}

为什么不写成这样呢?删掉 <T> 不是看上去更简单吗

function identity(arg: T): T {
    return arg;
}
2788 次点击
所在节点    问与答
16 条回复
abbycin
2020-05-28 15:22:14 +08:00
你要写 cpp 还会看到 template<typename T> auto identify (T arg) -> T { return arg ; }
hua123s
2020-05-28 15:48:07 +08:00
type T = {
我还用不用了
}
Aynamic
2020-05-28 15:52:25 +08:00
图一你可以理解为 T 是一个未确定的类型,调用方法时候可以指明 T 的类型,图二 T 是一个已知的类型。
wysnylc
2020-05-28 15:53:24 +08:00
也让你们体会下 Java 泛型带来的恐惧嘎嘎嘎
BingoXuan
2020-05-28 15:53:38 +08:00
<>是声明泛型用的吧,例如<T,S>就声明泛型 T 和 S 可以用。

我觉得 Python 的泛型声明才是最恶心的
eGlhb2Jhb2Jhbw
2020-05-28 15:59:17 +08:00
你觉得编译器怎么知道你是想用泛型还是手残敲出了个未定义的类型?
jswh
2020-05-28 16:01:31 +08:00
<T>里的 T 是声明,声明了之后后面才可以用鸭。
cxe2v
2020-05-28 16:07:36 +08:00
微软的泛型最早出现在.NET 里面,.NET 泛型的定义里有个类型参数,类型参数就是用来给实际类型使用时候的占位符,创建泛型类的时候,需要将 T 替换成实际类型,例如
```c#
public class identity{
public T A<T>(T arg){
return arg;
}
}

identity I=new identity();
I.A<int>(1);
```
你看如果没有`<T>`这个类型参数的话,编译器无法在编译期间就检查类型错误,会导致不必要的类型转换和可能的类型错误,而 typescript 是微软的面向对象编程语言,在设计上会有同样的形式,所以你这里的这个`<T>`不能够省略的
find456789
2020-05-28 16:08:17 +08:00
@jswh
@BingoXuan
@eGlhb2Jhb2Jhbw

哦 谢谢,似乎有一些明白了

冒昧再请教一下

问题 1: 如果我不加<T>, 编译器 有可能以为 T 是一个自定义的 interface 或者 type 对吗?

问题 2: 如果我加了 <T>, 就是 先告诉编译器,接下来的 T 是个泛型,而不是自定义 interfa 、type, 对吗
winnerczwx
2020-05-28 17:18:18 +08:00
在 c#里可以这样简写
killergun
2020-05-28 20:34:56 +08:00
看看 C#的泛型就知道了
Jirajine
2020-05-28 20:45:51 +08:00
泛型就是把类型参数化,<T>的意思是接收一个类型作为参数,后面的 T 是在使用这个参数。就像一般的变量把数据参数化一样。
mxalbert1996
2020-05-28 21:23:24 +08:00
楼主是不是以为泛型的类型只能用 T 表示?然而并不是。
CosimoZi
2020-05-28 21:25:48 +08:00
有兴趣可以读点范畴论,对泛型的本质会有更深的理解.本质上像 lz 举例的带泛型的函数表达了自然变换(natural transformation),和一般的函数在数学意义上就不一样.
aguesuka
2020-05-28 23:45:33 +08:00
java 里面可以这样调用泛型函数 identity<MyType>(param); 在 param 是 lambda 的时候,有时尖括号是不能省略的
BingoXuan
2020-05-29 15:30:16 +08:00
@find456789
是的,泛型是根据范型使用的上下文推断的类型。如果泛型声明时离开了使用上下文,那就没有意义了。所以需要通过<T,...>声明,并传递给上下文使用。

如果不结合运用泛型的上下文来声明,糟糕的例子就是 python3 的泛型了。简直就只多此一举。代码量一多,泛型声明就被淹没 了。具体类型和泛型用起来一毛一样。如下代码,你完全不知道有没有用到泛型,如果提前声明 T 是类型 str,那么扔一个 int 其实会报类型不正确的。

def Add(a:T,b:T)->T

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/676318

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX