00:00
好了,接下来我们来看下一个知识点,我们来新建一个TS文件啊,我们叫做零八,我们来说什么呢?哎,说一下我们叫做一个泛型,哎,何为泛型?哎,不着急,我们先看这么一个东西啊,现在呢,我想定一个函数,这个函数呢,简单点就叫做一个这个FNFN里面接了一个参数,比如说我叫一个A的类型呢,是一个number。诶,它的返回值的类型也是number,这个函数比较无聊,干什么呢?我返回的值呢,就是A,所以这个函数的作用也很明显,就是接收一个参数A,然后最后把这个A的这个值给它作为返回值,返回没什么用的,这么一个函数,OK,虽然没什么用,但是我们用它做一个这个,哎,说明一个问题,那我们现在去定义一个这个函数啊,或者说去定一个类的时候啊,我们用定一个变量,我们知道这个参数的类型,比如说A,我们知道它的类型是number,哎,我们也知道它的返回值是number,在这儿我就可以直接去写上这个number,但是有一些情况下,诶,我们不知道参数的类型,你比如说我这个A的类型我不知道是什么,它可能是任意类型,可能是一个number,可能是一个string,可能是一个玻璃,可能是任意的这个类型,那返回值也就会干嘛呀。
01:22
返回值的类型呢,是不是也就不确定了,因为我们返回值就是返回的这个变量本身嘛,所以这个时候A的类型是啥,返回值的类型它就是啥,那这个时候我们说遇到不确定的类型要怎么办呢?哎,有同学说了,哎老师啊,我这我可以用I啊,A的类型是I,返回值的类型呢,也是any,也是any,那这样不就行了吗?这样你传什么不就都可以了吗?这样可不可以,当然可以,这样当然能解决这个问题,但是我们之前也说了这个安的问题,就是我们用安妮以后,他实际上会关掉我们TS当中个类型检查,那这样我们如果用I的话,我们的这个这个这个这东西是不是就没有意义了,诶并且呢,还有一个问题就是我们现在A的类型是I,返回值的类型也是埃,从我们这个方法,这个函数的定义上,我们来看,我们能不能看出这个返回值的类型和A是一样的。
02:21
不能吧,我们只知道他俩都是任意类型,但是这里边它并不能体现出我们这个类型是相同的,所以凡是遇到这种我们类型不明确的时候,我们就可以什么呢?可以使用到这个泛型,哎,我们什么时候用在我们这个定义什么呢?定义函数啊,哎或什么呢?或是我们这个类时,哎如果什么呢?如果遇到我们这个类型不明确的,哎,我们就可以什么呢?哎,就可以使用我们这个泛型,哎,使用我们这个泛型,那这个泛型是干嘛的?泛型其实就是一个不确定的类型,我不知道这个类型具体是什么,因为我们这个要根据实际的调用情况来看,比如说AA的类型我不确定,我需要根据实际的使用情况,我调的时候我要传的是一个string,那么A的类型就是string,我传的是number,那么A的类型就是number,这个要根据调用的情况来具体的去,哎具体的看这种情况,那么这个泛型我们要怎么去指定呢?很简单,我们定义函数的时候,Function后边一个FN,那在之前我们直接FN后边就加括号了,在这里我们现在要用泛行了,我可以直接在FN后边加一个三角,加一个尖括号,尖括号里写一个K,因为描述类型通常我们会用大写,因为类型呢就是大写对吧,那所以这个时候我这儿就定义了一个泛型,这个泛型的名字叫什么呢。
03:52
哎,叫做一个K,你说老师是不是非得叫K啊,不一定叫啥都行,你说我叫T行不行,叫T也行,这个名字无所谓啊,无所谓,那比如说你叫T吧,那这个时候我就指定好了一个泛型T,这个T表示什么意思,这个T就表示的是一个任意类型,其实它有点像一个变量,X类型,T类型具体是什么现在不知道,只有调用的时候才能知道,然后后边就一样了,我们就直接写括号,括号里边我们是不是写参数啊,哎,我直接还是一个参数,诶这个时候我这不用写I了,我写什么呢?我写T啊,我写T表示什么?A的类型是T类型,注意为什么我这能用T,因为我这里是不是定义了T。
04:36
如果你在这里没有定义T这个泛型,这个T是用不了的,定义了才可以去用,然后呢,后边紧跟着一个冒号,我们这儿来一个T啊,来一个T,然后大括号我们来一个return一个这个,诶,那这样我们这个函数就给它定义完了,那这个T的话,在这里就是一个泛型,那你说T到底具体是什么类型啊,不知道,就是T类型,这个类型执有在我们函数执行的时候才可以确确定啊,才可以确定好,那这个函数我们就定义完了,好处是什么呀?比I逆的好处,首先我不用I逆,不用I逆就避免了把我们类型检查给跳过了,这第一个,第二一个我这里边是不是也能体现出我的第一个参数和我的返回值,它的类型是相同的,哎,是相同的,所以这样的话,我们怎么用啊怎么用啊,哎,那首先的话,它的好处比它就很明显啊,我不用指定具体类型,而且的话也能体现出这两个类型是相同的。
05:36
怎么用呢?用也很简单,第一种方式我们可以什么呢?可以直接去调用,具有这个泛型的一个函数,直接调,我直接来一个FN,我来一个十,我直接调一个,那这样的话,它会自动判断出,因为我们这个A的类型是不是number啊,它会自动判断出这个T的类型是number,那它等于就等于我们这传值的时候,就等于是给这个T进行了赋值,把number赋值给了T,也就是意味着我们这次调用的时候,这个泛行T的值就是number啊,参数类型是number,返回值的类型也是number,就这么一个东西,非常简单,但是这种方式实际上利用到了我们TS里的类型的自动推断,TS自动判断啊,你这个泛型T的类型是number,哎,我们还可以什么呢?有的时候这个推断呀,它推断不出来啊,他可能你这个设计的比较复杂,它推断推断不出来,推断不出来我们可以怎么办呢。
06:36
可以这样写,我直接FN后边尖括号啊间号,我写一个这个string,我这来一个括号,我写一个hello,什么意思呢?这个时候等于我是在手动的指定,手动的指定我们这个T泛型是谁呢?是死准,那这样也可以,所以这里边注意我们这儿不指定泛型,不指定泛型我们TS可以什么呢?可以自动对我们这个类型进行推断,但并不是所有的情况都能推断出来啊,这要注意这个玩意儿我们叫什么呢?叫指定泛型,那就是你指定的什么,它就是什么啊,你指定的是string,它就是string,你指定的是number,它就是number,就这么简单啊,有一个泛型好,当然了,这里边其实你要看它的结果,我们来一个,这儿来一个light,一个ret result,等于它这儿的话我们也来一个,诶,这我就别来了,这我来一个light,一个ret result2等于它由于我们这个。
07:36
不同,那我们第一个的返回值的类型,它就会是一个什么呀,Number,因为泛型是number嘛,第二个返回值类型就是一个什么呢?哎,就是一个这个,诶就是一个死准啊,就是一个死准,诶看到这儿你可能又会觉得,哎呀我的天呐,太麻烦了,哎太麻烦了,没办法,我们这种静态类型的语言,它就是一个效果和我们之前的GS当然是稍微有点麻烦,但是好处就是什么?好处就是现在我们拿到的两个变量类型是明确的,我们在用的时候,我们就能明确到我这个变量的类型,它到底是什么啊,是什么让我们这个结构变得更加的清晰,更加的清楚啊,泛型就这么指令啊,那这时候再看,那这个泛型我是不是只能指定一个呀?
08:20
诶,不是泛型,我可以指定多个,哎,啥意思呢?在这我们再整一个方个人,我们来一个哎,来一个S2,我直接来一个哎,来一个T逗号,来一个K,那这里的话就表示我指定了两个泛型,一个泛型叫T,一个泛型叫K,那我用的时候也可以用这两个。A冒号一个TB冒号一个,呃一个K,返回值呢,是这个T,我们在这儿直接return一个这个A,哎还是这么一个意思啊,这个B,这个参数可能现在没用上,但是我们就演示一下,我打印一下B吧,啊打一下B啊那就是这么一个意思,那现在的话,我们在调的时候也是你可以传两个泛型,比如说我传我不传,我传一个123传一个这个哈,那这样它就会自动进行这个什么呢?诶自动进行推断,推断什么呢?诶推断这个第一个参数是这,诶不是FN啊FN2推断什么呢?诶第一个参数你传的是一个number,那么T呢就是number,第二个呢,传的是一个字符串,那么K呢,就是这个字符串,当然我们也可以指令,而且我们其实建议我们写的时候,最好把这范型手动的给他指令上,这样的话,他也能降低我们这个出错的一个出错的一个几率啊,这是范刑,然后呢,还有一种用法,就是我们这个范刑现在指定起来的话,它实际上有点这个范围太大了,等于我这写。
09:40
了一个T啊,写了一个K,那这样实际上就表示说我这个型可以是任意类型,那有一些情况下,我想限制一下我的这个泛型的范围,那怎么办呢?诶我们举个例子啊,举个例子在这儿我们来写一个这个interface啊,我们写一个接口,我们来一个int亚来一个inter尔in特里边的话,它就有一个属性叫做一个这个诶Les lth lens的类型呢,是一个number,那现在在这我还是想用到这个泛型function,我们想用到泛型,比如说我来一个FN3,我还是想用到这个泛型,那这个时候的话,比如说我这儿就一个泛型,我们这儿叫做一个T,我这个T这个泛型呢,OK,它也是一个泛型,但是我希望它的范围是什么呢?它的范围是特的子类,或者说就是实现了in特接口这个类,我可以怎么办呢?在这儿我就可以直接写一个X ten,一个in ten。
10:40
一个in特什么意思,就表示说我这个T是一个泛型,而且要求这个T必须要实现了这个in特,这个接口用的是啊这个它就不分什么,所有的就是都用,那这里边我们再定一个参数,我们直接来一个AA冒号的话,我们直接指定一个这个T返回值呢,我们写一个number,哎,反回这么写一个number,那这个时候我可以这样写,直接return一个叫做一个什么呢?A点一个Li。
11:11
就OK了啊就OK了,那这个时候我们要传,我们要给FN3 FN3去传参的时候,这个时候我们这个参数必须得实现了in inter接口,其实也不一定非得实现它,那就是什么呢?你必须得有什么呀,你至少你得有这个Les这个属性,你说我传一个这个123嘛,123里有没有,诶123是不是这儿它等于是也能用啊,哎也能用,那证明我们这个123里面它肯定是有这个什么呀,诶有这个Le似属性,因为我这是不是传的是一个字符串,哎字符串里有Les,那这里边我如果传的是一个数字,你看是不是就不行了,因为数字里没有Les,那我要传一个对象,我传一个对象里边只有一个这个内幕属性,内幕属性叫hello,你看是不是就不行啊,哎,但是我这里边有一个谁呢?我这里边一个Les属性,Les属性的值是十,这个时候我是不就能传了,哎能传了,所以这个时候这个表示什么意思,这个就表示说我们要用一个泛型,这个泛型要是因特的一个,诶实现类啊或者。
12:12
其实不一定非得传接口,传一个类呢,也可以啊也可以好,这里边我们简单的总结一下啊,这个是我们说的,我们这个泛型呢,哎,泛型可以同时指定多个。哎,同时指定多个,你写两个也行,写十个也行,写三个也行啊,可以同时指定多个,那这个呢,我们叫什么呢?T extend in,这么叫做这种泛型写法,这表示什么呢?这表示我们T啊,这个泛型T,泛型T必须是我们这个in的一个实现类啊,实现类或者的话,你也可以说是一个子类啊,子类,但是子类的话,当然我们就需要传一个类啊,或者抽象类都行,这不一定需要传这个接口啊,这也就是一个泛型,除了在函数当中可以使用的话,在我们这个类当中也可以用泛型,比如说我定一个class class呢,我们就写一个my class my class my class呢,我们给也是在class后边来一个T,定一个泛型,然后的话我们写一个name冒号一个T,那这样就表示我定一个参数,这个这个属性name name的值是T,用的时候也是一样,Constructor,我们来一个name冒号一个T干嘛呢?this.name等于name。
13:25
是一样的,你在创建它的时候呢,那你就可以直接来一个诶constant,我们来一个MC,等于一个new,一个麦,Class也是在后边去,你可以直接写一个,写一个孙悟空,那这样他就会自动判断出你这个泛型的类型是字符串,你也可以直接加一个肩块,写一个什么呢?写一个四顺,哎,你告诉他我这个泛形式是这个字串啊好,那这个就是我们的一个泛型,总而言之,言而总之泛型的作用就是在我们类型不明确的时候,给我们整一个变量,用这个变量来表示这个泛型,它就这么一个作用,非常的非常的简单啊,非常简单,那我们具体的使用场景还是在我们后边练习的话,随着说的话,随时再去用,但是像泛型啊,像接口这些东西,它实际上属于那种。
14:16
锦上添花的东西,它并不是说你说这个东西我不可代替,我必须要用,它不是说非得用,它可以不用啊,可以不用,但是不用它的话,可能我们写起来要麻烦一些,或者是带来一些不便,但并不是说它必须使用的,所以关于这个接口啊,泛型啊,抽象类这些东西,这些概念在我们T,在我们这个是我们这个S新的使用场景的话,暂时因为我们现在嗯还没做习,所以使用场景的话能还不是很明确,所以现在我们需要的是先把这些知识给它,诶理解一下,给它记一下,后边的话我们随着诶,随着这个练习,我们再去把这些东西再去进行一个哎巩固,再去加深一下我们的一个印象。好,关于泛型的话,我们就先说这么多啊,我们来听一下。
我来说两句