在其他语言中等效Php __invoke()

时间:2017-01-14 18:41:19

标签: php oop callable

是否有其他面向对象的语言,其中有一个等同于Php __invoke方法的概念,它允许将对象视为函数/可调用对象?

1 个答案:

答案 0 :(得分:1)

您需要允许operator overloading的语言,因为这就是PHP __invoke的设计类似。

例如,在C ++中,您可以执行以下操作:

#include <iostream>

class Test
{
    public:
        Test() : m_i(42) {}

        friend std::ostream& operator<<(std::ostream& os, const Test& t)
        {
            os << t.m_i;
            return os;
        }

        operator int()
        {
            return this->m_i;
        }

        void operator()()
        {
            std::cout << *this << std::endl;
        }

    private:
        int m_i;
};

int main(int argc, char* argv[])
{
    Test t;
    // calls the operator<< overload to print "t"
    std::cout << "t = " << t << std::endl;
    // calls the void operator()() to treat "t" as a function
    t();
    // calls the operator int() to treat "t" as an int type
    int i = t;
    std::cout << "i = " << i << std::endl;
    return 0;
}

在C#中,您可以执行以下操作:

class Test
{
    private int m_i = 42;
    public delegate void MyDelegate(params int[] parms);

    public static implicit operator int(Test t)
    {
        return t.m_i;
    }

    public static implicit operator MyDelegate(Test t)
    {
        return t.Invoke;
    }

    private void Invoke(params int[] parms)
    {
        foreach (int i in parms) {
            this.m_i += i;
        }
        Console.WriteLine("i = {0}", this.m_i);
    }

    public override string ToString()
    {
        return this.m_i.ToString();
    }
}

static void Main(string[] args)
{
    Test t = new Test();
    // calls t.ToString()
    Console.WriteLine("t = {0}", t);
    int d = t; // implicit cast to int
    Delegate g = t; // implicit cast to Delegate type
    Console.WriteLine("d = {0}", d);
    // invoke the method pointed to by the delegate
    g.DynamicInvoke(new int[] { 10, 20, 30 });
    d = t; // implicit cast
    Console.WriteLine("d = {0}", d);
}

尽管如此,虽然操作符重载可以很方便,但与任何语言功能一样,您可能需要考虑为什么您正在重载运算符,以及另一个更易于阅读的OOP习惯用法还不足以穿越多种语言。

例如,在所有这些示例中,在PHP中,您可以编写一个简单的函数重载,它可以满足您的需要,并且可以在多种语言中轻松读取:

PHP

class Test {
    $m_i;

    function Invoke() { return $m_i; }
    function Invoke($x) { return $m_i + $x; }
}

C ++

class Test {
    private: int m_i;
    public:
        int Invoke() { return this->m_i; }
        int Invoke(int x) { return this->m_i + x; }
};

C#

class Test {
    private int m_i;
    public int Invoke() { return this.m_i; }
    public int Invoke(int x) { return this.m_i + x; }
}

希望可以提供帮助。