开发者

How to define the return type of AS3 method that may return or not return a result?

开发者 https://www.devze.com 2023-02-20 05:40 出处:网络
publ开发者_开发问答ic function t() { if(xxx)return xxx; //don\'t return anything } How to define the return type for such method?A function either has to return nothing, or return something - it can
publ开发者_开发问答ic function t()
{
  if(xxx)return xxx;
  //don't return anything
}

How to define the return type for such method?


A function either has to return nothing, or return something - it can't do both. The reason being, what if you write this code:

var someValue = someFunction();

How would this code be handled if sometimes someFunction returned a value, and sometimes it didn't?

Your problem is a really common one, though, and there are several ways to work around it.

Sentinel Values

You can return special-case values that you treat as non-values (such as null, NaN, "", or -1). These special-case values are called sentinel values. The users of your function (maybe your own code) would check the result after calling it. If it gets one of the sentinel values back, it doesn't use the result.

Try-style Functions

You could also use a pattern commonly used in C#/.Net that they call "Try-methods", but you can call "Try-functions". Actionscript doesn't work exactly like C#, but we can get close enough for this pattern to work.

To do this, return Boolean, returning true if you have a value, and false if you don't. Then give your function an Object parameter, and populate a property with the actual return value:

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
}

Exceptions

If your method failed to do what it promised to do, you can throw an exception. Then you don't have to worry about what gets returned, because your code just dies.

Exceptions are great because people who call your code don't have to learn as much. They don't have to know that your function only succeeded if it doesn't return some magic value that is different for every function, they don't need to check if your function returns true/false, and they don't need to know that some property gets populated on an object when the function succeeded.

Without exceptions, if they forget to check for your special value, or the result of a "Try-function", an error might happen further on in the program. Or it might not happen at all, and the program will continue running, but be broken. In these cases, it is much harder to track down the problem.

With exceptions, your code just blows up the second it detects a problem, and gives you the line of code where your program realized it couldn't work correctly.

If it is normal and okay for your function to fail, though, you probably shouldn't throw an exception. You should probably use a "Try-function" or a sentinel value instead.


Everything that Merlyn says is fine, though perhaps a bit of overkill. If your method needs the potential to return null, then just pass xxx back whether it's null or not...

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

... since you're going to have to do check the special condition in the calling method anyway:

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

Some people think that this is wrong and advocate creating a special 'null value' object in your return class, like this:

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

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

then in your function either return an interesting MyReturnType or NULL:

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

but then you've not really improved your caller method so why bother?

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

Whatever you choose to do, eventually you're just going to have to test for special cases in the caller method. Personally I'd say it's better to keep it as simple as possible, and the special 'null value' in your class is over-complication.


I write plenty of functions that might return an object reference, but may also return null, like this:

public function findThingById( id:int ):MyThingType
{

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

    if (found)
    {
       return thing;
    }

    return null;
}

Wherever you call a function that might return null, you would either test the return value for null explicitly, or if you expect null just don't do anything with the return value. For built-in data types, you would use a special value rather than null (like NaN for Numbers illustrated above), but the principle is the same.


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

so something like:

private function derp():void{

}

private function derp2():int{

}

private function derp3():Boolean{

}

etc

its always good practice to define the return type, and return an indicator variable if false (i.e return -1 for number), but if its really necessary you can do this:

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

don't specify a return type at all, and either it will return xxx or undefined, but I highly encourage using a return type.

But since flash runs on virtual memory it can basically adapt to your return type so it makes it a little flexible so you can return what ever.

EDIT:

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

EDIT:

so lets say you want the condition with a return type of int you would have

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

this when we get back any number other then negative 1 we know the condition was true, but if we get -1 the condition was false. But if you numbers are any real numbers, use NaN keyword:

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

this way if you get NaN back it means your condition was false

I should also mention that when your dealing with NaN use the isNaN() to determine if the return type was NaN or not:

example:

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


There is no way a single function can return void as well as returning a type. This is because void is not part of any inheritance chain, it is a top level concept meaning something very specific; it doesn't return anything.

Don't get confused between null and void, undefined and void, NaN and void. They are different concepts.

The answer to your question is simply that it can't, nor should it be done. When you hit a problem like this, it's good practice to step back and ask 'why' do you need to do this.

I would highly encourage that you mark this question as closed, and instead posted a higher level problem. For example,

How would I structure a class that has a variable xxx that does this and that and will be eventually set to a number when the user clicks. But if the user never clicks, it will be unset.... ecetera ecetera....

If you are 100% convinced you should do something like you're asking, you could 'fake' it by

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

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

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

But remember, from that point onwards you will need to check everytime xx is used to see if it undefined. Otherwise it will lead to errors.

0

精彩评论

暂无评论...
验证码 换一张
取 消