泛型
一、泛型、为什么需要泛型
-
泛型
泛型是一种参数化类型,泛型的核心作用是解除类或者方法所受类型的限制,使得代码能够更加的通用,极大的提高了代码的复用率。泛型的产生为程序员提供了便利,程序员可以充分发挥自己的想象,尽可能的抽象方法或者类的行为表达,使用较少的代码提供更为通用的功能。
-
为什么需要泛型
1、泛型提供了编译期检查的功能,代码在编译期就能发现其中的错误,增强了代码的健壮性
2、泛型是自动化转型的,不同于Java中的继承等,会存在强制转型带来的不安全性,增加了代码的安全性
3、增加了代码的可读性、通用性和稳健性,使得一套代码可以适用一类场景
二、泛型困境是什么
-
泛型困境
泛型其实是一把双刃剑,既可能给开发者带来了便利,但是同样会带来编译和效率的问题。
要么苦了程序员,要么苦了编译器,要么降低运行时效率。
即,要么程序员苦一些,编译器负担轻一些,要么就是编译器工作多一些,程序员使用舒服一些,当然运行的效率和不同语言泛型的编排有关。
三、Golang里面的泛型
-
Go语言中把泛型(Generic)叫做类型参数,Go语言在原来的函数名和函数参数列表之间插入了一组方括号,来表示类型参数。
-
语法总结
参考文档:https://taoshu.in/go/generics/design.html
函数可以定义类型参数: 可以在函数名称的后边,使用中括号声明一个额外的类型参数列表,例如 func F[T any](p T) { ... } 可以在参数声明和函数体中使用类型参数指定类型。 类型定义也可以指定类型参数: 可以在类型名称的后边,使用中括号声明一个额外的类型参数列表,例如 type M[T any] []T。 type Stack[T any] struct { eles []T } 类型参数必须指定类型约束: func F[T Constraint](p T) { ... }。 使用泛型函数或者类型需要传入类型参数。 通过泛型推导可以减少指定类型参数,简化泛型的使用。
-
举例
package main import ( "fmt" ) type Addable interface { int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64 | complex64 | complex128 | string } func add[T Addable](a, b T) T { return a + b } func main() { fmt.Println(add(1, 2)) fmt.Println(add("foo", "bar")) }
四、Java里面的泛型
-
在Java中,为了方便接收参数类型的统一,提供了一个统一的Object类,Object 类是所有类的父类,也就是说Java 的所有类都继承了Object,子类可以使用Object 的所有方法。 Object 类位于java.lang 包中,编译时会自动导入。因此可以利用Object类对象接收所有类型的数据。
不过,使用Object类对象虽然可以接收所有类型的数据,但是由于Object类是一个顶级的父类,数据范围过大,在数据的使用过程中,容易出现数据类型的强制性向下转型,使得执行出现了不安全性。
-
Java泛型的设计意义在于:类中的属性或者方法的参数与返回值的类型采用动态标记,在对象实例化的时候动态配置需要使用的实际数据类型,有效避免了Object接收参数所带来的ClassCastException问题。
-
举例:
// 泛型接口 interface T0 <T>{ public void toString(T ...t); } // 泛型类 class Point<T> implements T0<T>{ private T x; private T y; public void setX(T x){ this.x = x; } public void setY(T y){ this.y = y; } public T getX(){ return this.x; } public T getY(){ return this.y; } // 泛型方法 public void toString(T ...t){ for (T p:t) { System.out.println("坐标:" + p); } } public String getPoint() { return "Point{" + "x=" + x + ", y=" + y + '}'; } } public class Test { public static void main(String[] args) { Point<Integer> point = new Point<>(); point.setX(10); point.setY(10); point.toString(point.getX(),point.getY()); System.out.println(point.getPoint()); } }