带你PHP中的泛型之基础知识浅析

泛型基础知识

泛型就是在类或者方法定义时不指定具体类型,在使用时再确定具体要使用的类型。泛型可以增强程序的灵活性和可维护性,减少代码冗余,提高代码的复用率和稳定性。

1. 泛型的定义

我们可以用以下方式定义一个泛型类:

class GenericClass {

private $t;

public function set(T $t) {

$this->t = $t;

}

public function get() {

return $this->t;

}

}

在这个定义中,我们使用了泛型占位符T来代表待确定的具体类型,T可以代表任意类型,当我们实例化GenericClass时,可以通过尖括号<>指定具体类型,如:

$g = new GenericClass<string>();

$g->set('hello');

echo $g->get();

在这个例子中,泛型变量T被确定为string类型,$g实例化的类GenericClass也就是具备了存储字符串的能力。

2. 泛型方法

我们可以使用泛型方法来定义复杂的操作,比如对一个数组进行排序:

function sortByLength(array &$arr) {

usort($arr, function($a,$b) {

//比较两个字符串的长度

return strlen($a) - strlen($b);

});

}

在上例中,我们通过usort函数实现了按字符串长度排序的函数sortByLength,但只能用来排序字符串,如果要排序其他类型的数据,要写另外一个函数。这时候就可以使用泛型方法,将方法参数的类型拓展为T,实现对任意类型的数据排序:

function sortByLengthGeneric(array &$arr, callable $compare) {

usort($arr, function($a,$b) use ($compare) {

//使用比较函数来比较两个元素

return $compare($a,$b);

});

}

//使用sortByLengthGeneric函数进行排序

$arr = [1, 22, 333, 4, 55, 6666];

sortByLengthGeneric($arr, function($a,$b) {

return strlen((string)$a) - strlen((string)$b);

});

print_r($arr);

这样我们就实现了对于任意数据类型的排序,只需要传递一个比较函数即可。

3. 泛型接口

接口也可以使用泛型:

interface GenericInterface {

public function get(): T;

}

//实现泛型接口

class StringGetter implements GenericInterface<string> {

private $str;

public function __construct(string $str) {

$this->str = $str;

}

public function get(): string {

return $this->str;

}

}

在这个例子中,我们定义了一个泛型接口GenericInterface,约定了一个get方法,要求实现类返回指定类型的数据。我们实现了泛型接口,并取指定返回类型为string。当我们实例化StringGetter时,可以获得指定类型的数据。

总结

泛型可以让我们的程序更加灵活,增强了代码的可维护性和可读性,使用泛型能够让我们的代码更加简洁,有效减少了代码的冗余。掌握与应用泛型也必将是一个优秀的PHP开发工程师的必备技能。

后端开发标签