85호. PHP 7.4 화살표 함수 (Arrow Functions) free

2019-12-02

PHP 7.4가 릴리즈되었습니다. 오늘부터 PHP 7.4에 추가된 새로운 기능을 하나씩 소개해드릴까 합니다. 첫 번째로 소개해드릴 기능은 화살표 함수입니다.


"짧은 클로저"라고 부르기도 부르기도 하는 화살표 함수는 클로저를 조금 더 간략하게 작성할 수 있는 기능입니다.


RFC에 있는 예를 봅시다.


function array_values_from_keys($arr, $keys) {
return array_map(function ($x) use ($arr) { return $arr[$x]; }, $keys);
}

위의 일반 클로저를 화살표 함수로 쓰면 아래와 같이 쓸 수 있습니다.


function array_values_from_keys($arr, $keys) {
return array_map(fn($x) => $arr[$x], $keys);
}

이름 그대로 클로저 부분이 짧아졌음을 볼 수 있습니다.


유용성을 더 음미해보기 위해 RFC에 있는 예제를 몇 개 더 보죠.


silexphp/Pimple 코드에 적용하는 예제입니다.


$extended = function ($c) use ($callable, $factory) {
return $callable($factory($c), $c);
};

// with arrow function:
$extended = fn($c) => $callable($factory($c), $c);

44문자가 8문자로 줄었습니다.


Doctrine DBAL에 적용한 예제에서는 31문자가 8자로 줄어드네요.


$this->existingSchemaPaths = array_filter($paths, function ($v) use ($names) {
return in_array($v, $names);
});

// with arrow function
$this->existingSchemaPaths = array_filter($paths, fn($v) => in_array($v, $names));

tpunt가 제공한 예제입니다.


$result = Collection::from([1, 2])
->map(function ($v) {
return $v * 2;
})
->reduce(function ($tmp, $v) {
return $tmp + $v;
}, 0);

echo $result; // 6

// with arrow functions:
$result = Collection::from([1, 2])
->map(fn($v) => $v * 2)
->reduce(fn($tmp, $v) => $tmp + $v, 0);

echo $result; // 6

익숙해지면 가독성이 매우 좋아질 것 같습니다.


그럼 이제 사용법과 특징을 살펴보겠습니다.


1. fn 키워드를 사용합니다.


2. 한 개의 표현식만 사용할 수 있습니다.


이 기능의 목적 자체가 기존 클로저를 좀 더 간략하게 쓰기 위한 것이기 때문에, 두 줄을 넘어가는 클로저는 이 기능을 써봐야 큰 이득이 없기 때문에 그렇게 만들었다고 합니다. 하지만 향후에는 여러 줄을 지원할 가능성도 있다고 합니다.


3. 표현식은 자동으로 반환됩니다. return 키워드는 사용하지 않습니다.


4. 외부 변수도 use 키워드 없이 사용할 수 있습니다.


5. 클래스 매서드 내에서 사용하면 $this 변수, 스코프, 늦은 정적 바인딩 스코프가 자동으로 바인딩 됩니다.


class Test {
public function method() {
$fn = fn() => var_dump($this);
$fn(); // object(Test)#1 { ... }

$fn = static fn() => var_dump($this);
$fn(); // Error: 객체 컨텍스트가 아닌 곳에서 $this를 사용함
}
}

6. 인자와 리턴 타입을 타입힌트 할 수 있습니다.


fn(array $x) => $x; // $x가 배열이 아니면 에러
fn(): int => $x; // $x가 int가 아니면 에러

7. 레퍼런스 사용 가능


인자와 리턴 값은 기본적으로 값을 바인딩(by-value variable binding)합니다.


$x = 1;
$fn = fn() => $x++; // 외부 값에 영향을 주지 않습니다.
$fn();
var_dump($x); // int(1)

원하면 레퍼런스를 사용할 수도 있습니다.


fn(&$x) => $x; // 인자에 레퍼런스
fn&($x) => $x; // 리턴 값에 레퍼런스

8. 스프레드 오퍼레이터 사용 가능


function complement(callable $f) {
return fn(...$args) => !$f(...$args);
}

위에 언급한 여러 기능을 고려하여 여러 가지 시그니처를 갖습니다. 아래의 모든 시그니처가 유효합니다.


fn(array $x) => $x;
fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

마치며


이상으로 PHP 7.4에 소개된 화살표 함수 소개를 마칩니다. 참고로, PHPStorm에 클로저를 화살표 함수로 바꿔주는 기능이 추가되었다고 하네요.



오늘도 즐거운 코딩 생활 되세요~


1일 1식 라라벨 85호

2019년 12월 2일


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.