泛型是Java里头比较有意思且有用的一个东西了。
一个简单的例子:
public static Integer parse(Integer a1, Integer a2){
if(a1.equals(a2)){
return a1;
}
return a2;
}
public static Float parse(Float a1, Float a2){
if(a1.equals(a2)){
return a1;
}
return a2;
}
可以看到,两个方法其实做的同一个工作:
if(a1.equals(a2)){
return a1;
}
return a2;
只是因入参类型的不同,所以才需要才拆分成了不同的方法。
例子中的代码量是极小的,但是在实际项目中,同一个处理逻辑可能达到相当惊人的代码量,可以预见项目中的重复代码,直接降低了代码的可读性,提高了代码维护成本。
如果这时候用上了泛型:
public static <T> T sum(T a1, T a2){
if(a1.equals(a2)){
return a1;
}
return a2;
}
程序将自动按照传入参数处理,而无需重复编写相同的代码逻辑,代码简洁程度得到了极大的提升。
关于Java中泛型的其他用法,这里就不再使用过多篇幅赘述了。
Java存在泛型,那么Python是否存在泛型呢?
Python是属于弱类型的编程语言,即不强制输入输出类型:
def parse(a1, a2):
if a1 == a2:
return a1
return a2
这个代码在python3中也可以这样子表示:
def parse(a1: Any, a2: Any) -> Any:
if a1 == a2:
return a1
return a2
即输入输出类型都是可以任意的,并不做强制要求,这本身应也是Python语言的一个优点。
不过在一些情况下,比如多人协作的大项目中,尽可能的统一入参出参,会更有利于代码的复用及规范的制定统一。
在Python2之前制定出入参类型实际没有办法完成,直到Python3中才引入了输出输出类型的指定。
开篇的Java例子使用Python编写:
def parse_int(a1: int, a2: int) -> int:
if a1 == a2:
return a1
return a2
def parse_float(a1: float, a2: float) -> float:
if a1 == a2:
return a1
return a2
可以看到,实际也是会存在一堆重复的逻辑,那么Python是否可以使用泛型优化此代码呢?
答案当然是可以的,Python3的typing模块引入了相应支持:
from typing import TypeVar
T = TypeVar("T")
def parse(a1: T, a2: T) -> T:
if a1 == a2:
return a1
return a2
一些复杂的情景,比如指定类型的list或者dict:
from typing import Dict, List
T = TypeVar("T")
def list_dm(a1: List[T]) -> List[T]:
pass
def dict_dm(a1: Dict[T, T]) -> Dict[T, T]:
pass
当然,还有一种较为复杂的场景,在Java中表示如下:
public class MyQueue<T>{
public void push(T obj){
// 新增数据到队列
}
public T pop(){
// 从队列中获取元素
return null;
}
}
即对象中直接声明泛型,其下方法默认操作的类型均为该类型。
在Python中,可以用typing模块的Generic实现同样的操作:
T = TypeVar("T")
class MyQueue(Generic[T]):
def push(self, obj: T) -> None:
pass
def pop(self) -> T:
pass
简单记录下,就先到这里啦 ~