2012-03-28 6 views
3

Возможно ли, чтобы метод возвращал разные значения в зависимости от контекста (как используется возвращаемое значение)? Например, может ли метод возвращать $this, когда он используется с оператором стрелки для вызова другого метода (т. Е. Вызовов метода цепочки), но возвращает скаляр, когда возвращаемое значение не используется таким образом?Цепочка функций с различными значениями возврата?

Случай 1:

$result = $test->doSomething1(); // returns 4 
// $result returns 4 

Случай 2:

$result = $test->doSomething1()->doSomething2(); 
// doSomething1() returns $this 
// doSomething2() returns 8 

Есть в любом случае, чтобы выполнить такое поведение?

+2

Почему «$ test-> doSomething1()« return '4' (case 1) и' $ this' (case 2)? –

+0

То, что вы действительно хотите сделать, невозможно, теперь мне интересно, вы действительно этого хотите, или вы не поняли вопрос? –

+0

@GabrielSantos Да, я хочу этого, это было бы намного проще, чем хранить ценность и тянуть это после моих цепных функций. –

ответ

4

Если Я правильно понял вопрос, вы хотите, чтобы метод (doSomething1) возвращал значение в зависимости от того, как выглядит остальная цепочка вызовов. К сожалению, вы абсолютно не можете это сделать.

Общие парадигмы программирования «все» языки (как методы, операторы и такая работа в con текст грамматики) диктуют, что результат выражения $this->doSomething1() должен быть разработан до того, как можно будет рассмотреть результат возможного вызова ->doSomething2(). Статически типизированные и динамически типизированные языки делают это по-разному, но общий фактор заключается в том, что выражение $this->doSomething1() должно рассматриваться независимо от следующего или не следовать.

В двух словах: $this->doSomething1() должен возвращать определенный тип значения в обоих случаях. И в PHP нет способа иметь тип значения, который может вести себя как число в одном контексте и как объект с методами для вызова в другом.

+0

+1. Что касается вашего замечания о «всех» языках: я думаю, что Python может согласиться на такой синтаксис, но я не уверен, так как я не использую все это часто. Любые эксперты Python в комнате? – Daan

3

Невозможно, чтобы функция возвращала разные значения в зависимости от того, вызвана ли другая функция возвращенным значением или нет. Вы можете эмулировать с ToString() (где преобразование в строку применимо, или другая функция, которую вы называете в конце каждой цепочки, чтобы получить значение вместо объекта:

$test = new foo(); 
echo $test->doSomething1(); // Outputs 1 

$test = new foo(); 
echo $test->doSomething1()->doSomething2(); // Outputs 3 

$test = new foo(); 
$result = $test->doSomething1()->done(); // $result === 1 

$test = new foo(); 
$result = $test->doSomething1()->doSomething2()->done(); // $result === 3 

class foo { 

    private $val; 

    function __construct($val = 0){ 
     $this->val = $val; 
    } 

    function doSomething1(){ 
     $this->val += 1; 
     return $this; 
    } 

    function doSomething2(){ 
     $this->val += 2; 
     return $this; 
    } 

    function done(){ 
     return $this->val; 
    } 

    function __toString(){ 
     return (string)$this->val; 
    } 

} 

Codepad Example

0

This answer предлагает создать стек вызовов внутри класса, чтобы вы могли отслеживать, где вы находитесь, в цепочке методов. Это можно использовать для возврата $this или чего-то еще, в зависимости от контекста.

+1

Нет, он не может использоваться для возврата '$ this' или еще чего-то. Этот ответ неявно * всегда * возвращает '$ this'. – Jon

+1

@ Jon, я думал использовать этот стек стека вызовов, предложенный в этом ответе, чтобы решить, что вернуть. Оглядываясь назад, я понял, что это невозможно, потому что информация, требуемая для этого решения, будет доступна только после того, как метод уже будет возвращен (когда вызывается второй, цепной метод). – bfavaretto

Смежные вопросы