📜 ⬆️ ⬇️

Why is an early return from a function so important?

Hi, Habr! I present to you the translation of the article “Why should you return early?” By Szymon Krajewski

image

At the beginning of my adventure as a programmer, my code often resembled vermicelli. In any conditional expression, all I did was that I immediately turned to the description of the correct outcome, leaving the rest to the end. “It works, that's all,” I told myself, and the code continued to grow by leaps and bounds. Thousands of written methods in the end made me think about whether it was not worth changing their internal logic, returning negative results as early as possible. Thus, I came to what is now called the rule of “immediate failure”.
')
Obviously, there are several approaches to writing the same function. For example, as you can start the execution of the main part immediately after the positive outcome of the conditional operator, you can first run through all the negative outcomes, returning errors from the function, and only then go to the main logic. In other words, I discovered different styles of writing conditional constructions.

Two approaches to checking requirements


, - , . , , $email , $message . .

function sendEmail(string $email, string $message)
{
    if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
        if ($message !== '') {
            return Mailer::send($email, $message);
        } else {
            throw new InvalidArgumentException('Cannot send an empty message.');
        }
    } else {
        throw new InvalidArgumentException('Email is not valid.');
    }
}

, . ? . ? .

?


sendMail():

  1. ;
  2. ;

« », . , return . , , . - « ».

function sendEmail(string $email, string $message)
{
    if (! filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new InvalidArgumentException('Email is not valid.');
    }

    if ($message === '') {
        throw new InvalidArgumentException('Cannot send an empty message.');
    }

    return Mailer::send($email, $message);
}

, else , , , . , « » (. , ).

, « »?


, , . , – .

, , « ». , Jim Shore Martin Fowler “Hello world”. , , « ». , « ».

« »


.
« » — , , , .
, , . « », « » « »? .

« »


« », ? ? , « ». , . sendMail, , . « », « ».
image


, . , .


. email , . . , . . , . .

« » — , . :

function matrixAdd(array $mA, array $mB)
{
    if (! isMatrix($mA)) {
        throw new InvalidArgumentException("First argument is not a valid matrix.");
    }

    if (! isMatrix($mB)) {
        throw new InvalidArgumentException("Second argument is not a valid matrix.");
    }

    if (! hasSameSize($mA, $mB)) {
        throw new InvalidArgumentException("Arrays have not equal size.");
    }

    return array_map(function ($cA, $cB) {
        return array_map(function ($vA, $vB) {
            return $vA + $vB;
        }, $cA, $cB);
    }, $mA, $mB);
}

, , .


– . , . updatePostAction PostController:

/* PostController.php */

public function updatePostAction(Request $request, $postId)
{
    $error = false;

    if ($this->isGranded('POST_EDIT')) {
        $post = $this->repository->get($postId);

        if ($post) {
            $form = $this->createPostUpdateForm();
            $form->handleRequest($post, $request);

            if ($form->isValid()) {
                $this->manager->persist($post);
                $this->manager->flush();

                $message = "Post has been updated.";
            } else {
                $message = "Post validation error.";
                $error = true;
            }
        } else {
            $message = "Post doesn't exist.";
            $error = true;
        }
    } else {
        $message = "Insufficient permissions.";
        $error = true;
    }

    $this->addFlash($message);

    if ($error) {
        $response = new Response("post.update", ['id' => $postId]);
    } else {
        $response = new RedirectResponse("post.index");
    }

    return $response;
}

, , . , « ».

/* PostController.php */

public function updatePostAction(Request $request, $postId)
{
    $failResponse = new Response("post.update", ['id' => $postId]);

    if (! $this->isGranded('POST_EDIT')) {
        $this->addFlash("Insufficient permissions.");
        return $failResponse;
    }

    $post = $this->repository->get($postId);

    if (! $post) {
        $this->addFlash("Post doesn't exist.");
        return $failResponse;
    }

    $form = $this->createPostUpdateForm();
    $form->handleRequest($post, $request);

    if (! $form->isValid()) {
        $this->addFlash("Post validation error.");
        return $failResponse;
    }

    $this->manager->persist($post);
    $this->manager->flush();

    return new RedirectResponse("post.index");
}

« ». : , - , — . . -, else .


.

function reverse($string, $acc = '')
{
    if (! $string) {
        return $acc;
    }

    return reverse(substr($string, 1), $string[0] . $acc);
}

« »


, ? ?

1. –


, , , . - . , , . « » , .

. - , - . , , .

image
, ?

2. « » —


, « » . -, false:

public function setUrl($url)
{
    if (! $url) {
        return;
    }

    $this->url = $url;
}

. , , , :

public function setUrl($url)
{
    if ($url) {
        $this->url = $url;
    }
}

3. break


return, , . , , . , , ?

4. return


, « » . :

function nextState($currentState, $neighbours)
{
    $nextState = 0;

    if ($currentState === 0 && $neighbours === 3) {
        $nextState = 1;
    } elseif ($currentState === 1 && $neighbours >= 2 && $neighbours <= 3) {
        $nextState = 1;
    }

    return $nextState;
}

:

function nextState($currentState, $neighbours)
{
    if ($currentState === 0 && $neighbours === 3) {
        return 1;
    }

    if ($currentState === 1 && $neighbours >= 2 && $neighbours <= 3) {
        return 1;
    }

    return 0;
}

, .


, , . , , , . , .

« » , 100% , . , , .

« » , , . , , :
.



: .

Source: https://habr.com/ru/post/348074/


All Articles