- 将闭包生成器中的引用捕获从 & 改为 =,避免悬空指针问题 - 在 PHP 中使用 = 赋值进行浅拷贝,仅增加一次引用计数 - 添加了关于 zval 封装赋值的注释说明 - 新增了可调用语法的测试用例,包括箭头函数和杂项功能 - 添加了对 PHP 8.1+ 首类可调用语法的支持测试 - 包含了枚举相关功能的测试用例验证pull/1/head
parent
b499347669
commit
dd297b5f92
4 changed files with 222 additions and 1 deletions
@ -0,0 +1,87 @@ |
|||||||
|
--TEST-- |
||||||
|
Backed Enums (PHP 8.1+) |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
// Test basic backed enum with int values |
||||||
|
enum Status: int { |
||||||
|
case Pending = 0; |
||||||
|
case Active = 1; |
||||||
|
case Suspended = 2; |
||||||
|
case Closed = 3; |
||||||
|
|
||||||
|
public function label(): string { |
||||||
|
return match($this) { |
||||||
|
self::Pending => 'Pending', |
||||||
|
self::Active => 'Active', |
||||||
|
self::Suspended => 'Suspended', |
||||||
|
self::Closed => 'Closed', |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Test backed enum with string values |
||||||
|
enum Color: string { |
||||||
|
case Red = 'red'; |
||||||
|
case Green = 'green'; |
||||||
|
case Blue = 'blue'; |
||||||
|
|
||||||
|
public function rgb(): array { |
||||||
|
return match($this) { |
||||||
|
self::Red => [255, 0, 0], |
||||||
|
self::Green => [0, 255, 0], |
||||||
|
self::Blue => [0, 0, 255], |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Test enum in switch |
||||||
|
function processStatus(Status $status): string { |
||||||
|
return match($status) { |
||||||
|
Status::Pending => 'Task is pending', |
||||||
|
Status::Active => 'Task is active', |
||||||
|
Status::Suspended => 'Task is suspended', |
||||||
|
Status::Closed => 'Task is closed', |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
var_dump(Status::Pending->value); |
||||||
|
var_dump(Status::Active->label()); |
||||||
|
var_dump(Status::from(2)->name); |
||||||
|
|
||||||
|
var_dump(Color::Red->value); |
||||||
|
var_dump(Color::Green->rgb()); |
||||||
|
|
||||||
|
var_dump(processStatus(Status::Active)); |
||||||
|
|
||||||
|
// Test enum comparison |
||||||
|
var_dump(Status::Active === Status::Active); |
||||||
|
var_dump(Status::Pending !== Status::Active); |
||||||
|
|
||||||
|
// Test enum array usage |
||||||
|
$statuses = [Status::Pending, Status::Active, Status::Closed]; |
||||||
|
foreach ($statuses as $status) { |
||||||
|
var_dump($status->label()); |
||||||
|
} |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(0) |
||||||
|
string(6) "Active" |
||||||
|
string(9) "Suspended" |
||||||
|
string(3) "red" |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
int(0) |
||||||
|
[1]=> |
||||||
|
int(255) |
||||||
|
[2]=> |
||||||
|
int(0) |
||||||
|
} |
||||||
|
string(14) "Task is active" |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
string(7) "Pending" |
||||||
|
string(6) "Active" |
||||||
|
string(6) "Closed" |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
--TEST-- |
||||||
|
First-Class Callable Syntax (PHP 8.1+) |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
// Test callable returning callable |
||||||
|
function multiplier(int $factor): callable { |
||||||
|
return fn(int $value) => $value * $factor; |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
// Test callable returning callable |
||||||
|
$double = multiplier(2); |
||||||
|
$triple = multiplier(3); |
||||||
|
|
||||||
|
var_dump($double(5)); |
||||||
|
var_dump($triple(5)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(10) |
||||||
|
int(15) |
||||||
@ -0,0 +1,110 @@ |
|||||||
|
--TEST-- |
||||||
|
First-Class Callable Syntax (PHP 8.1+) |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
// Test basic first-class callable |
||||||
|
function add(int $a, int $b): int { |
||||||
|
return $a + $b; |
||||||
|
} |
||||||
|
|
||||||
|
// Test first-class callable with class methods |
||||||
|
class Math { |
||||||
|
public static function multiply(int $a, int $b): int { |
||||||
|
return $a * $b; |
||||||
|
} |
||||||
|
|
||||||
|
public function divide(int $a, int $b): float { |
||||||
|
return floatval($a) / $b; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Test callable returning callable |
||||||
|
function multiplier(int $factor): callable { |
||||||
|
return fn(int $value) => $value * $factor; |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
$callable = 'add'; |
||||||
|
var_dump(array_map($callable, [1, 2, 3], [4, 5, 6])); |
||||||
|
|
||||||
|
$staticCallable = ['Math', 'multiply']; |
||||||
|
var_dump(array_reduce([[2, 3], [4, 5]], fn($carry, $item) => $carry + call_user_func_array($staticCallable, $item), 0)); |
||||||
|
|
||||||
|
$math = new Math(); |
||||||
|
$instanceCallable = [$math, 'divide']; |
||||||
|
var_dump(call_user_func($instanceCallable, 10, 4)); |
||||||
|
|
||||||
|
// Test first-class callable with arrow functions |
||||||
|
$filter = fn(array $arr): array => array_filter($arr, fn($n) => $n > 0); |
||||||
|
var_dump($filter([1, -2, 3, -4, 5])); |
||||||
|
|
||||||
|
// Test callable in array operations |
||||||
|
$numbers = range(1, 5); |
||||||
|
$doubled = array_map(fn($n) => $n * 2, $numbers); |
||||||
|
var_dump($doubled); |
||||||
|
|
||||||
|
$squared = array_map(fn($n) => $n ** 2, $numbers); |
||||||
|
var_dump($squared); |
||||||
|
|
||||||
|
// Test callable with usort |
||||||
|
$unsorted = [5, 2, 8, 1, 9]; |
||||||
|
usort($unsorted, fn($a, $b) => $a <=> $b); |
||||||
|
var_dump($unsorted); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
int(5) |
||||||
|
[1]=> |
||||||
|
int(7) |
||||||
|
[2]=> |
||||||
|
int(9) |
||||||
|
} |
||||||
|
int(26) |
||||||
|
float(2.5) |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
int(1) |
||||||
|
[2]=> |
||||||
|
int(3) |
||||||
|
[4]=> |
||||||
|
int(5) |
||||||
|
} |
||||||
|
array(5) { |
||||||
|
[0]=> |
||||||
|
int(2) |
||||||
|
[1]=> |
||||||
|
int(4) |
||||||
|
[2]=> |
||||||
|
int(6) |
||||||
|
[3]=> |
||||||
|
int(8) |
||||||
|
[4]=> |
||||||
|
int(10) |
||||||
|
} |
||||||
|
array(5) { |
||||||
|
[0]=> |
||||||
|
int(1) |
||||||
|
[1]=> |
||||||
|
int(4) |
||||||
|
[2]=> |
||||||
|
int(9) |
||||||
|
[3]=> |
||||||
|
int(16) |
||||||
|
[4]=> |
||||||
|
int(25) |
||||||
|
} |
||||||
|
array(5) { |
||||||
|
[0]=> |
||||||
|
int(1) |
||||||
|
[1]=> |
||||||
|
int(2) |
||||||
|
[2]=> |
||||||
|
int(5) |
||||||
|
[3]=> |
||||||
|
int(8) |
||||||
|
[4]=> |
||||||
|
int(9) |
||||||
|
} |
||||||
Loading…
Reference in new issue