00:00
背后的一部分内容,我们来讲解一下skyla当中的泛型,泛型这个概念大家其实并不陌生,因为不管是在Java还是其他的一些编程语言,其实都渐渐的引入了泛型这样一个概念。那什么是泛型呢?字面上理解,泛型应该就是一个宽泛的泛指的类型,那在具体定义的过程当中呢,往往我们是用在一个集合类型上边,然后给它追加一个类型,表示当前集合类型里边的元素到底是什么样子的,那在Java里边我们是用一个尖括号来表示,而在SKY当中呢,是用一个方括号来表示,具体在代码当中,我们可以看一个具体的例子。比如说我们的内方法直接传入参数AX,它的类型就是一个string类型的ARA,我们说是一个字符串数组这个定义,这就是一个带着泛型的定义,我们看到array后边有中括号,中括号里的string表示的是数组元素的类型,那当前的这个A瑞本身在定义的时候又是怎么定义的呢?我们看起来当前这个string应该是传进来的,所以阿瑞里边呢,本身定义的时候我们看到后边是一个D,它表示的就是当前。
01:24
元素的类型,数组元素的类型可以不确定,我只以T在这里做一个表示,那为什么我们要这样去定义呢?啊,其实如果没有泛型的话,我们会想到也可以用统一的父类类型或者祖先类型来表示所有的情况啊,比如说在Java里边我们有object,哎,我们定义一个a list啊,那直接就把它定义成a list,然后不加任何的泛型。里边所有的元素来了之后,我都当成一个object把它保存起来不就完了吗?哎,或者在skyla当中,我们这里边定义RA的时候,后面不加泛型,所有的数据来了之后都是一个any类型,没有问题啊,可以放进去,这样是很简单,但是定义的时候简单,我们使用的时候就麻烦了,大家可以想象一下啊,如果这个时候我们想要去对于当前的数组内的元素做一个操作的话。
02:18
如果是比较通用的操作还比较简单,比方说是to string啊,那比方说我们像Java里面object或者skyla里的an底层就对这个图斯string有一个调用的方法,那相当于这就是多肽嘛,我们可以在运行时绑定元素具体的那个对象的方法,这是没有问题的,但是假如说我们当前它里边具体的那个数据类型相差很大,我们要调用的是不同的方法,完全不一样,比方说int要调的方法,诶,那string里边根本就没有string要调的方法,别的数据类型里边也没有,那这个时候怎么办呢?你直接基于object或者基于any去做调用显然就不成立了,那就必须要把当前的。
03:02
比较宽泛的这一个父类类型要转,强制转换转换成子类类型,所以这里面就涉及到了一个强转的问题,这样的话我们代码非常的麻烦,而且强转的时候还有出现运行时异常的风险,因为大家知道这里边我们在写代码的过程当中,编译器并不知道我们到时候运行的时候要传入什么值,那肯定编译是不报错的,但是运行的时候呢,如果我们现在调了一个int的方法,强转成int,而传进来的是一个string,那肯定就会报错了。哎,所以代码的可读性和稳定性其实都不好的,我们在定义的时候就需要对于当前数组的元素类型要做一个限定。哎,那大家可能想这也简单呀,你要这么说的话,我们就像Java里边的基本数据类型定义数组的时候那样,Int后面加一个中括号,哎,或者说这个string。
04:02
加一个中括号,这样不就可以对应的定义我们相关的这些数组类型了吗?每一个具体的类型都能定义出来,哎,但是大家想这样的话就太麻烦了啊,那就相当于我们可能定义一个阿瑞。T。里边对应对于这个int类型的数组里边有各种各样的这个操作的方法,诶之前我们讲过啊,数组里边我们可以啊获取它对应的这个长度,可以根据它某一个索引位置去获取对应的值啊,还有其他的一些各种各样的转换方法,那如果说当前的元素类型变成了string的话,我们再定义一个string。里边定义的方法是不是完全雷同啊,哎,所以这个就明显是一个浪费嘛,没有必要把每一个具体的类型都定义一个。专门定义一个类型出来,数组类型出来,那怎么样解决这个问题呢?解决方案就是。
05:01
分析,看到这里A瑞的定义,我们并没有定死它到底是具体元素是什么类型,而是只给了一个泛指的T,这就有点像我们是传入了一个类型参数,这个T就是一个参数。我们只有在真正运行使用它的时候,才会把具体的类型传进去,告诉编译器当前这个数组里边所有的元素是什么类型。那所以我们在具体调用的时候就限定死了具体的元素类型,就呃也不会出现强转的这样这样的问题了,而且代码的稳定性和可读性也会更好。所以在在这里边我们定义的是通过泛型定义出了更加通用的一个数组类型,我们会看到在scda当中所有的集合类型都是这样去定义的,这就是泛型的意义非常的重要。
我来说两句