![Flutter从0基础到App上线](https://wfqqreader-1252317822.image.myqcloud.com/cover/259/33831259/b_33831259.jpg)
4.2 泛型
本章的最后一节,我们来谈谈泛型。在声明一个变量时,通常会用到var,即没有定义是何种类型,因为在Dart编程语言中,类型是可选的。那么,既然类型是可选的,为什么还要用泛型、泛型如何使用,以及它的典型应用场景是什么呢?通过本节的学习,你就能得到答案。
4.2.1 泛型的作用
在Dart中,使用泛型的两个目的:第一,简化相同的逻辑;第二,限制可使用的类型。下面我们结合实际的案例来体会上述两点。现在,有这样一个需求:使用星号(*)打印如下所示的实心直角三角形。
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_82.jpg?sign=1738786122-iODQPtUt0doi6KwJAcYgvQrLViYFA9Ot-0-16642b799f77069b5f2f89e23ddc4a10)
当然,建议你先自己尝试。具体算法实现如下所示:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_83.jpg?sign=1738786122-yasGbJUvGGb6EvoeEF1JX5Fgn7bKByom-0-00e1e031bc34a9614d469a9d95bd5ed9)
4.2.2 泛型的使用示例
对于上例,如果考虑使用加号(+)、减号(-)等情况,难道就要写一堆printTriangle()方法吗?当然不用,仅需对上述代码稍加修改就可满足多种需求。参考如下代码:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_84.jpg?sign=1738786122-baVvY5Ade7LgzwXYCkjsoCJJ7Bsxq0sm-0-f5b41d2e8dbe3eb5abbc2a10caf6980b)
运行后的输出结果依然是由星号组成的直角三角形。当需要用加号或其他字符来拼这个三角形时,只需要更改调用它的位置的参数就可以了。在上述代码中,我们用T取代String来充当类型占位符。这是一个典型的泛型的应用。
4.2.3 限制泛型类型范围
我们发现,在上例的代码中char类型被强制转换成了String类型。这一操作存在风险,如果传入的参数是一个数字,就会出现类型相关的异常:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_85.jpg?sign=1738786122-kMAlZ9nvEi2j6jxbtv5p0fh3DlW2vC9l-0-a07f31222e8ffa1ffe977bb3b1ca3b47)
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_86.jpg?sign=1738786122-PKprT3ajORwllHOfV8Xy2RW9v0qEr7OT-0-73d26263a39d621e9bb29e8d11407592)
因此,为了保证程序的正常运行,就要限制传入的类型仅为String。限制泛型的类型要用extends关键字,具体方法如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_87.jpg?sign=1738786122-WIcfe5DdeYx8mT6QnvG5Ol34GqEV89Nk-0-79ffc6fb51000d9d79472b93cdf9215f)
可以看到,代码第一行改成了Textends String,此处的char类型也无须转换成String类型。此时,如果在调用它的位置传入了非String类型的变量,就会出现编译错误而无法运行,杜绝了在运行时异常的发生。
4.2.4 使用泛型方法
在Dart的早期版本中,泛型只能在类上使用。目前,Dart已经支持在方法上使用泛型了。上例中,printUseChar()方法无返回值,如果想得到输出的字符串,而不是单纯地只在这个方法中输出到控制台,就需要返回整个字符串,代码如下:
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_88.jpg?sign=1738786122-plbWSUGs6ZRDgaQWfBDSx7uuDF0yzPW2-0-0fae7931af2608781ef085008dbbff5e)
![img](https://epubservercos.yuewen.com/9CF474/18096059801207706/epubprivate/OEBPS/Images/txt004_89.jpg?sign=1738786122-lPFPR0GBRuCoPhiqkqrKytwEZEl72W0L-0-da98e8f6183f85a552971ce2ba8bc18e)
在这段代码中,泛型作为返回值用在了方法上。由于我们之前限制了类型范围,因此,此处返回的依然是String类型,strForPrint变量保存了输出的字符串的值。