目录

什么是泛型

泛型允许编码人员在强类型程序设计语言中编写代码时,使用一些以后才指定的类型,在实例化时作为参数指明这些类型。

各种语言和其编译器、运行环境对泛型的支持均不一样。比如Delphi、Java、C#、Swift 和 .NET 称为泛型(generics),而ML、Scala 和 Haskell 称为参数多态(parametric polymorphism),C++ 和 D语言称为模板。

如何处理泛型

单纯的php开发者可能都不清楚java、c++,包括golang开始要支持的泛型,到底是什么,为什么在php圈子里没有什么人讨论泛型的问题?

我们先看下其他语言如何处理泛型的:

  • C

    通过void*和强制类型转换来实现,也可以通过宏来实现类似功能,一般只会用作简单的实现

  • C++

    模板类的模板具体化,预编译时生成不同的类,分别进行编译,代码会膨胀,但由于不需要在运行时进行任何的类型识别,程序也会变得比较干净,运行效率也更高。

  • JAVA

    基于类型擦除,在编译泛型类时将强制消除类型信息;JVM运行时泛型类并不知道自己处理的具体是何种类型。

  • Go

    当前版本不支持泛型,可以通过 interface{}强制转换实现泛型。也可以通过第三方库,实现模板库类型的泛型。

  • C#

    泛型类在编译生成中间码IL时,通用类型T只是一个占位符。

    在实例化类时,根据实际数据类型代替T并由即时编译器(JIT)生成本地代码运行,不同封闭类的本地代码是不一样的。

  • JS、Python

    动态类型天然支持泛型

php需要泛型吗

那php需不需要泛型呢?我们看个几个对话回帖了解java泛型,以及php是否需要泛型:


天地炫舞 09:39:18

我先学习过java,然后又学习了PHP,在使用面向对象的思想编写的一个小例子的时候发现了一个问题,为何PHP不加入泛型技术,虽说PHP是弱语言类型,但是加入泛型的却会方便很多的啊,请看下面的例子:

interface Usb{
    function start();
}
class Upan implements Usb{
    function start(){
        echo "upan";
    }
}
class SDcard implements Usb{
    function start(){
        echo "sdcard";
    }
}
function useUU($u){
    $u->start();//这里如果加上泛型不是更加方便么
}
$upan=new Upan();
$sdcard=new SDcard();
useUU($upan);
useUU($sdcard);

天地炫舞 09:58:31

哈哈 和java一样啊

function useUU($u<Usb>){
    $u->start();//这里如果加上泛型不是更加方便么
}

这样的话,变量$u就可以直接调用start()方法了


天地炫舞 11:40:43

我认为这就是应用泛型技术应该解决的问题啊,当useUU()方法被调用的时候,泛型自动根据传入的参数实例化一个对象。

例如当传入的是upan对象时,泛型把变量$u实例化为upan对象,再来调用对应的方法。

在php代码底层应该也是这样操作的啊,当有对象传入的时候,变量$u获得upan对象的引用,再来调用upan对应的方法。增加泛型无非是在函数未被调用前,可以调用指定对象的方法。不要纠结这里定义的接口不能实例化啊,如果我把Usb改为一个类呢,我利用代码重写,子类重写父类方法,再利用多态的思想,根据传入不同的子对象,来调用不同的方法。


xuzuning 12:31:02

泛型只是允许多种类型(只要符合事先的约定) 实际上就是弱类型

但永远也不会无中生有


天地炫舞 12:49:02

给你一个java代码:

package com.wllfengshu;
interface Usb{
    void start();
}
class Upan implements Usb{
    public void start(){
        System.out.println("Upan");
    }
}
class SDcard implements Usb{
    public void start(){
            System.out.println("SDcard");
        }
    }
    public class Generi{
        public static void useUU(Usb u){
        u.start();
    }
    public static void main(String[] args) {
        Upan upan=new Upan();
        useUU(upan);
    }
}

并没有无中生有啊,我们不能说PHP现在设计的没有泛型,你就一直否定泛型啊。PHP虽说是弱类型,但是如果能增加某种方法使之能在强弱之间自由切换,也就是增加强语言类型的功能,岂不是更好。


xuzuning 15:07:11

你这个代码和你主贴的php代码有什么区别呢?

无非就是没有把

function useUU($u){

写作

function useUU(Usb $u){

如果你原意加上类型限定,php 也是支持的,但这绝不是泛型,而是强制类型


天地炫舞 19:14:51

刚试了下,的确PHP可以这样使用,加上PHP又没有类似java中集合的概念,的确没有必要增加泛型,PHP还是学的太浅了,谢谢指教


小结

php不是强类型语言,php完全可以在运行时才指定变量类型,所以php本身是不需要泛型的,如果说php7有严格的类型要求,硬套泛型的概念的话,我们也可以说php本身是支持泛型的。