匿名関数を宣言するときに静的が必要なのはなぜですか?

つい先日、私の電報チャンネルの 1 つの投稿に関して、ある購読者から質問がありました彼はこのコードの断片に戸惑いました。





<?php

usort($firstArray, static function($first, $second) {
    return $first <=> $second;
});
      
      



質問は次のように聞こえました。





なぜ usort コールバックを静的にするのですか?





そして、これは注意を払うべき非常に良い質問だと思いました。





何が問題ですか?

同期するドキュメントの定義から始めましょう:





クロージャーとも呼ばれる匿名関数を使用すると、特定の名前を持たない関数を作成できます。これらは呼び出し可能なパラメータ値として最も有用です が、他の多くの用途もあります。





匿名関数はClosureクラスを使用して実装され ます。





そこに、しかしほとんど誰もこれを読んでいません:





クラスのコンテキストで宣言すると、現在のクラスが自動的にそれに関連付けられ、クラスの関数内で $ this を使用できるようになります。現在のクラスに自動的にリンクしたくない場合は、静的匿名関数を使用します





, losure , . , $this



:





,
<?php

class ExampleTest extends TestCase
{
 
    public function testBasicTest(): void
    {
        $array = [2, 1];
        usort($array, function ($first, $second) {
            var_dump($this);
            return $first <=> $second;
        });

     	  self::assertTrue(true);
    }

}
      
      



" ", .





, $this, , , , .





static:





<?php 

class LargeObject {
    protected $array;

    public function __construct() {
        $this->array = array_fill(0, 2000, 15);
    }

    public function getItemProcessor(): Closure {
        return function () { //    
            $a = 1;
            $b = 2;
            return $a + $b;
        };
    }
}

function getPeakMemory(): string
{
    return sprintf('%.2F MiB', memory_get_peak_usage() / 1024 / 1024);
}
$start = microtime(true);

$processors = [];
for ($i = 0; $i < 2000; $i++) {
    $lo = new LargeObject();
    $processors[] = $lo->getItemProcessor();
}

var_dump(getPeakMemory());

      
      



, string(10) "134.10 MiB"







, static 11 , string(8) "1.19 MiB"







, processors[]



, losures , , , .





, static . static, , .





P.S.

. - https://t.me/beerphp. .








All Articles