PHP 8.5 新特性 闭包可以作为常量表达式了
PHP 8.5 新特性 闭包可以作为常量表达式了
PHP 8.5 又带来了一个让人兴奋的新特性:闭包现在可以作为常量表达式使用了,这意味着它们可以出现在默认参数或属性值中。
你是不是也遇到过这种情况:想在 PHP 中把闭包设置为默认参数值,结果只能想各种变通方案?在 PHP 8.5 中,这个烦恼终于没了。闭包现在可以作为常量表达式——也就是说,它们可以用在任何你之前只能用字面值的地方。
我之前就被这个限制坑过,而且不止一次。现在,你可以在这些地方使用闭包了:
- 默认参数值
- 常量值
- 属性默认值
- 属性参数值
- 还有更多
默认值
以前,我会写这样的代码:
function someFunction(mixed $someValue, ?callable $callback = null): bool
{
$callback ??= fn () => true;
return $callback($someValue);
}
或者这样:
final class SomeClass
{
private Closure $someCallable;
public function __construct()
{
$this->someCallable = function (mixed $value): bool {
// 待实现
return true;
};
}
}
有了闭包常量表达式,这两个例子都可以简化成:
function someFunction(
mixed $someValue,
callable $callback = static function () { return true; },
): bool {
return $callback($someValue);
}
final class SomeClass
{
private Closure $someCallable = static function (mixed $value): bool {
// 待实现
return true;
};
}
不用再写 $callback ??= 这种绕来绕去的代码了。直接把闭包作为默认参数值是我经常要做的事,现在能够通过避免像 null 这种无意义的值来精简公共接口,这个改进真的很棒。
属性(Attributes)
这是另一个很赞的改变——你现在可以直接在属性中定义函数了。比如:
#[Attribute(Attribute::TARGET_PROPERTY)]
final readonly class TruthyValidator
{
public function __construct(
public Closure $truthyValidator = static function(mixed $value): bool {
return (bool) $value;
}
) {
}
}
这是一个简单的验证器属性,用来检查值是否为真值,默认实现就是把它转成布尔值,让 PHP 自己处理转换。但假如你想把字符串 '0' 也当作真值:
#[TruthyValidator(truthyValidator: static function(string|int|null $value): bool {
return $value === '0' || $value;
})]
public string|int|null $someProperty = null;
First-Class Callables
严格来说这是一个独立的 RFC,但它是因为投票原因才拆分的,技术上并不是独立的,所以我在同一篇文章里一起介绍。
除了标准的闭包(你可以内联定义函数体),现在你也可以用 first-class callables 作为常量表达式了。这意味着上面所有的例子也都适用于它们。
<?php
// 定义一个默认验证器
function defaultValidatorFunction(mixed $value): bool
{
return (bool) $value;
}
// 定义验证器类
#[Attribute(Attribute::TARGET_PROPERTY)]
final readonly class TruthyValidator
{
public function __construct(
// 使用 first-class callable 语法分配默认验证器
public Closure $truthyValidator = defaultValidatorFunction(...),
) {
}
}
// 定义我们自定义的验证函数
function truthyValidatorWithoutZeroString(string|int|null $value): bool
{
return $value === '0' || $value;
}
class SomeClassToBeValidated
{
// 用 first-class callable 的方式使用它
#[TruthyValidator(truthyValidator: truthyValidatorWithoutZeroString(...))]
public string|int|null $someProperty = null;
}
总结
我个人真的很喜欢这个新特性,因为它——就像最近的很多其他改进一样——让 PHP 变成了一门更简洁、更一致的语言,减少了各种 hack 和怪异的语法。
PHP 8.5 新特性 闭包可以作为常量表达式了的更多相关文章
- Java1.8新特性——接口改动和Lambda表达式
Java1.8新特性——接口改动和Lambda表达式 摘要:本文主要学习了Java1.8的新特性中有关接口和Lambda表达式的部分. 部分内容来自以下博客: https://www.cnblogs. ...
- java8新特性(二)_lambda表达式
最近一直找java8相关新特性的文章,发现都太没有一个连贯性,毕竟大家写博客肯定都有自己的侧重点,这里找到一本书,专门介绍java8新特性的,感觉大家可以看看<写给大忙人看的JavaSE8> ...
- Java8新特性(一)——Lambda表达式与函数式接口
一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...
- 现代 PHP 新特性 —— 闭包
一.概述 闭包是指在创建时封装周围状态的函数,即使闭包所在的环境的不存在了,闭包中封装的状态依然存在.闭包对象实现了__invoke()魔术方法,只要变量名后有(),PHP就会查找并调用__invok ...
- Java8新特性第1章(Lambda表达式)
在介绍Lambda表达式之前,我们先来看只有单个方法的Interface(通常我们称之为回调接口): public interface OnClickListener { void onClick(V ...
- jdk8新特性-亮瞎眼的lambda表达式
jdk8之前,尤其是在写GUI程序的事件监听的时候,各种的匿名内部类,大把大把拖沓的代码,程序毫无美感可言!既然Java中一切皆为对象,那么,就类似于某些动态语言一样,函数也可以当成是对象啊!代码块也 ...
- Java8新特性学习笔记(一) Lambda表达式
没有用Lambda表达式的写法: Comparator<Transaction> byYear = new Comparator<Transaction>() { @Overr ...
- Java8新特性 利用流和Lambda表达式对List集合进行处理
Lambda表达式处理List 最近在做项目的过程中经常会接触到 lambda 表达式,随后发现它基本上可以替代所有 for 循环,包括增强for循环.也就是我认为,绝大部分的for循环都可以用 la ...
- Spring Boot 2.4 新特性,全新的Cron表达式处理机制
说起 cron 表达式大家一定不陌生,我们常用来作为定时任务执行策略规则. 在 Spring Boot 框架中 cron 表达式主要配合 @Scheduled 注解在应用程序中使用. 在 Spring ...
- Java8新特性【转】
地址:http://ifeve.com/java-8-features-tutorial/ 1.简介 毫无疑问,Java 8是自Java 5(2004年)发布以来Java语言最大的一次版本升级,Ja ...
随机推荐
- SciTech-Mathematics-PAS概率统计-多学多用MATLAB就非常的好-Distribution分布-Binomial + Poisson +
https://ww2.mathworks.cn/help/stats/poisson-distribution.html https://ww2.mathworks.cn/help/stats/bi ...
- 关于MathJax
首先说一下使用感受吧: MathJax:一堆奇奇怪怪的错误,渲染慢的同时一堆错. $\KaTeX$:渲染比较快,也比较轻量,但是仍然渲染会有问题.比如这里. 怎么说呢,单从配置难度来讲,$\KaTeX ...
- 在 .NET 中使用内存映射文件构建高性能的进程间通信队列
目录 前言 什么是内存映射文件(Memory-Mapped File) 如何在 .NET 中使用 MMF 创建内存映射文件 使用 MemoryMappedViewAccessor 来直接读写结构体数据 ...
- Django实战:Python代码规范指南
一.PEP 8:Python 代码风格的基石 在团队协作和项目维护中,一致的代码风格至关重要.它不仅能提高代码的可读性,还能减少沟通成本,提升开发效率. PEP 8 是 Python 官方发布的代码风 ...
- linux下怎么用ssh连接另一台linux服务器-九五小庞
linux系统大家都知道是服务器版本一般都没有图像界面,通过字符界面操作.用ssh远程方式远程,如果要从一台linux远程到另外一台系统应该怎么操作呢本经验咗嚛以cenots7为例演示 方法/步骤 ...
- Win11系统打开电脑出现闪屏的问题
有电脑基地的用户,刚刚更新Windows 11系统电脑就开始闪屏,大家都说新系统好用,但是为什么会这样子呢?下面,技术员小编就来分享具体的解决方法. Windows 11 系统电脑闪屏可能是由驱动程序 ...
- Archlinux 玩原神
首先你需要一台装载了archlinux的电脑,配置的话本人: Lenovo TianYi510S-07IMB Intel Core i5-10400 × 12 内存 8.0 GiB 磁盘 1 TB 玩 ...
- Why框架的确定性与必然性,是人类的精神寄托与福音
ECT-OS-JiuHuaShan/ORCID:0009-0006-8591-1892 宇宙级确定性:人类精神的永恒锚点 您的论断揭示了最深层的本质.ECT-OS-JiuHuaShan 提供的绝非仅是 ...
- WebAR方案整理
最近在研究各种web实现AR的现有方案,整理一下,以下是国内外的部分现有方案 开源 非Web 以下几个是非Web平台的项目,web平台的技术基础 ARToolKit 最早的开源AR库,全平台,已经废弃 ...
- liveplayer免费网页直播_点播播放器-页面动态多播放器添加代码示例
强大的网页直播/点播播放器,使用简单,功能强大, 终身免费使用 支持m3u8播放; 支持HTTP-FLV播放; 支持RTMP播放; 支持直播和点播播放; 支持播放器快照截图; 支持点播多清晰度播放; ...