在 JavaScript 与 PHP 中关闭

Closure in JavaScript vs PHP

我正在尝试在 PHP 中实现一个非常简单的闭包相关任务,但进展不顺利。我在 JavaScript 中有这个解决方案。我如何在 PHP 中实现它?

const data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

const getChunksOfTwo = () => {
  let pos = 0
  
  return () => {
     const start = pos
     const finish = start + 2
     const chunk = data.slice(start, finish)
     pos++
     return chunk
  }
}

// To initiate the closure
const closureFun = getChunksOfTwo()

// Call the closureFun
closureFun() // Gives [1, 2]
closureFun() // Gives [2, 3]
closureFun() // Gives [3, 4]

但在 PHP 中显然不起作用。我正在尝试这个:

$data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];

function getChunksOfTwo($data) {
   $pos = 0;

   return function() {
     $start = $pos;
     $finish = $start + 2;
     $chunk = array_slice($data, $start, $finish);
     $pos++;
     return $chunk;
   };
};

// To initiate the closure
$closureFun = getChunksOfTwo($data);

// Call the closureFun
$closureFun(); // Does not give [1, 2]
$closureFun(); // Does not give [2, 3]

你可以试试这个

$data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];

function getChunksOfTwo($data) {
   $pos = 0;
   
   return function() use(&$pos, $data) {
     $start = $pos;
     $finish = 2;
     $chunk = array_slice($data, $start, $finish);
     $pos+=2;
     return $chunk;
   };
};

// To initiate the closure
$closureFun = getChunksOfTwo($data);

// Call the closureFun
print_r($closureFun()); // gives [1, 2]
print_r($closureFun()); // gives [2, 3]

$data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];

function getChunksOfTwo($data) {
   $chunks = array_chunk($data, 2);
   $pos = 0;
   
   return function() use(&$pos, $data, $chunks) {
     return $chunks[$pos++];
   };
};

// To initiate the closure
$closureFun = getChunksOfTwo($data);

// Call the closureFun
print_r($closureFun()); // gives [1, 2]
print_r($closureFun()); // gives [2, 3]

& with var 表示按引用传递 source

必须通过引用传递来改变该变量,否则它会复制原始变量,并且每个新调用都将具有相同的值。

输出

Array
(
    [0] => 1
    [1] => 2
)
Array
(
    [0] => 3
    [1] => 4
)

我提出了一个替代方案,为什么不使用 array_chunk

$data = [1,2, 3, 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
$chunk = array_chunk($data, 2);
$pos = 0;
print_r($chunk[$pos]);
$pos++;
print_r($chunk[$pos]);
$pos++;
print_r($chunk[$pos]);

输出:

Array
(
    [0] => 1
    [1] => 2
)
Array
(
    [0] => 3
    [1] => 4
)
Array
(
    [0] => 5
    [1] => 6
)

参考:

您的 php 代码中有两个问题。

首先是PHP中的一个闭包封装了它的作用域,这意味着它无法访问定义或执行它的作用域。但是,可以使用 use 关键字从父作用域(定义闭包的地方)将变量继承到闭包中。这继承了变量 by-value,使用其原始名称在闭包内提供了一个副本。

因为你想为每个函数调用保留 $pos 的值,你需要通过引用传递它 &$pos.

其次,phparray_slice的实现与js中的slice不同。因此,您需要更改 php.

中的输入
<?php
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

function getChunksOfTwo($data) {
    $pos = 0;

    return function () use ($data, &$pos) {
        $chunk = array_slice($data, $pos, 2);
        $pos++;
        return $chunk;
    };
};

// To initiate the closure
$closureFun = getChunksOfTwo($data);

// Call the closureFun
print_r($closureFun());
print_r($closureFun());
print_r($closureFun());