Как определить тип возврата метода AS3, который может возвращать или не возвращать результат? - PullRequest
1 голос
/ 27 марта 2011
public function t()
{
  if(xxx)return xxx;
  //don't return anything
}

Как определить тип возврата для такого метода?

Ответы [ 5 ]

3 голосов
/ 27 марта 2011

Функция либо должна ничего не возвращать, либо возвращать что-то - она ​​не может делать и то, и другое.Причина в том, что если вы напишите этот код:

var someValue = someFunction();

Как будет обрабатываться этот код, если иногда someFunction возвращает значение, а иногда нет?

Ваша проблемаоднако, это довольно распространенный способ, и есть несколько способов его обойти.

Значения часового

Вы можете возвращать значения специального случая, которые вы рассматриваете как не-значения (такие как null, NaN, "" или -1).Эти особые значения называются значениями дозорного .Пользователи вашей функции (возможно, ваш собственный код) проверят результат после вызова.Если он возвращает одно из значений часового, он не использует результат.

Функции в стиле попытки

Вы также можете использовать шаблон, обычно используемый в C #/ .Net, что они называют «Try-методы», но вы можете вызвать «Try-функции».Actionscript не работает точно так же, как C #, но мы можем подобраться достаточно близко, чтобы этот шаблон работал.

Чтобы сделать это, верните Boolean, возвращая true, если у вас есть значение, и falseесли нетЗатем задайте для своей функции параметр Object и заполните свойство фактическим возвращаемым значением:

function trySomeFunction(result:Object) : Boolean
{
    if(xxx)
    {
        result.Value = xxx;
        return true;
    }

    return false;
}

// ...

var result:Object = { Value:null };

if(trySomeFunction(result))
{
    // Do something with the value here
}

Исключения

Если ваш метод не смог выполнить то, что онобещал сделать, вы можете сгенерировать исключение .Тогда вам не нужно беспокоиться о том, что возвращается, потому что ваш код просто умирает.

Исключения велики, потому что люди, которые вызывают ваш код, не должны учиться так много.Им не нужно знать, что ваша функция выполнена успешно, только если она не возвращает магическое значение, отличающееся для каждой функции, им не нужно проверять, возвращает ли ваша функция истину / ложь, и им не нужнознать, что какое-то свойство заполняется в объекте при успешном выполнении функции.

Без исключений, если они забывают проверить ваше специальное значение или результат "Try-function", в дальнейшем может произойти ошибка.в программе.Или это может вообще не произойти, и программа продолжит работу, но будет прервана.В этих случаях гораздо сложнее отследить проблему.

За исключением, ваш код просто взрывается, как только обнаруживает проблему, и дает вам строку кода, где ваша программа поняла, что не можетработать правильно.

Если это нормально и нормально, что ваша функция не работает, вы, вероятно, не должны вызывать исключение.Вы, вероятно, должны использовать вместо этого «Try-function» или значение часового.

1 голос
/ 29 марта 2011

Я пишу множество функций, которые могут возвращать ссылку на объект, но также могут возвращать ноль, например:

public function findThingById( id:int ):MyThingType
{

    ... code here to search for/load/lookup thing with matching id

    if (found)
    {
       return thing;
    }

    return null;
}

Где бы вы ни вызывали функцию, которая может возвращать ноль, вы должны либо проверить возвращаемое значениедля нуля в явном виде, или если вы ожидаете, что ноль, просто не делайте ничего с возвращаемым значением.Для встроенных типов данных вы должны использовать специальное значение, а не ноль (например, NaN для чисел, показанных выше), но принцип тот же.

1 голос
/ 27 марта 2011

Все, что говорит Мерлин, хорошо, хотя, возможно, немного излишне.Если вашему методу нужен потенциал для возврата нуля, просто передайте xxx обратно независимо от того, равен он нулю или нет ...

public function t():MyReturnType
{
    return xxx;
}

... так как вам придется проверить специальное условие ввызов метода в любом случае:

public function caller():void
{
    var value:MyReturnType = t();
    if (value)
        doSomethingPositive();
    else
        copeWithNullState();
}

Некоторые люди думают, что это неправильно, и рекомендуют создать специальный объект с нулевым значением в вашем возвращаемом классе, например:

public class MyReturnType
{
    public static const NULL:MyReturnType = new MyReturnType(null);

    public function MyReturnType(identifier:String)
    ...
}

затем в вашемфункция либо возвращает интересный MyReturnType, либо NULL:

public function t():MyReturnType
{
    return xxx || MyReturnType.NULL;
}

, но тогда вы действительно не улучшили свой метод вызова, так зачем беспокоиться?

public function caller():void
{
    var value:MyReturnType = t();
    if (value != MyReturnType.NULL)
        doSomethingPositive();
    else
        copeWithNullState();
}

Что бы вы ни выбрали, в конечном итоге выПросто придется проверять на особые случаи в методе звонящего.Лично я бы сказал, что лучше держать его как можно более простым, а специальное «нулевое значение» в вашем классе - чрезмерное усложнение.

0 голосов
/ 27 марта 2011

Невозможно, чтобы одна функция могла возвращать void, а также возвращать тип. Это потому, что void не является частью какой-либо цепочки наследования, это концепция высшего уровня, означающая нечто очень специфическое; это ничего не возвращает.

Не запутайтесь между null и void, undefined и void, NaN и void. Это разные понятия.

Ответ на ваш вопрос прост: он не может и не должен этого делать. Когда вы сталкиваетесь с подобной проблемой, хорошей практикой будет отступить назад и спросить «почему», нужно ли вам это делать.

Я бы настоятельно рекомендовал вам пометить этот вопрос как закрытый и вместо этого опубликовать проблему более высокого уровня. Например,

Как бы я структурировал класс, у которого есть переменная xxx, которая делает это и то, и в конечном итоге будет установлена ​​на число, когда пользователь щелкнет. Но если пользователь никогда не щелкнет, он будет сброшен .... ecetera ecetera ....

Если вы на 100% убеждены, что должны сделать что-то, как вы просите, вы можете «подделать» это

function f():* {
    var xxx:Number = 999;

    if(xxx) {
        return xxx;
    } else {
        return undefined;
    }
}

var xx:* = f();
trace(xx);

Но помните, что с этого момента вам нужно будет проверять каждый раз, когда используется xx, чтобы увидеть, если это undefined. В противном случае это приведет к ошибкам.

0 голосов
/ 27 марта 2011
public function t():type
{
  if(xxx)return xxx;
  //don't return anything
}

так что-то вроде:

private function derp():void{

}

private function derp2():int{

}

private function derp3():Boolean{

}

и т.д.

это всегда хорошая практика, чтобы определить тип возвращаемого значения и вернуть переменную индикатора, если false (то есть, вернуть -1 для числа), но если это действительно необходимо, вы можете сделать это:

public function t()
{
  if(xxx)return xxx;
  //don't return anything
}

вообще не указывайте тип возврата, и он будет возвращать xxx или неопределенный , но я настоятельно рекомендую использовать тип возврата.

Но поскольку флэш-память работает на виртуальной памяти, она может в основном адаптироваться к вашему типу возврата, что делает ее немного гибкой, чтобы вы могли возвращать то, что когда-либо.

EDIT:

public function t()
{
  if(true){
    return xxx;   //xxx can by of any type
  }
  return NaN
}

EDIT:

Допустим, вы хотите, чтобы условие с типом возвращаемого значения int было бы

public function t():int
{
  if(true){
    return xxx;   //where xxx != -1
  }
  return -1
}

это когда мы возвращаем любое число, отличное от отрицательного 1, мы знаем, что условие было истинным, но если мы получим -1, условие было ложным. Но если ваши числа являются любыми действительными числами, используйте ключевое слово NaN:

public function t():Number
{
  if(true){
    return xxx;   //where xxx != -1
  }
  return NaN
}

таким образом, если вы вернете NaN, это означает, что ваше состояние было ложным

Я должен также упомянуть, что когда вы имеете дело с NaN, используйте isNaN (), чтобы определить, был ли возвращаемый тип NaN или нет:

пример:

if(isNaN(t()) == true){
    //if condition in function t() was false;
}
...