<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Resmic's | BLOG</title><link>https://blog.resmic.cn/</link><description>个人博客</description><item><title>PHP 8.4 新特性实战指南：属性钩子、非对称可见性与新数组函数</title><link>https://blog.resmic.cn/post/327.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260717080423178424666329747.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;PHP 8.4 正式发布，现代 PHP 迎来新时代&lt;/h2&gt;&lt;p&gt;PHP 8.4 于 2024 年 11 月正式发布，这是 PHP 语言近年来最具里程碑意义的版本之一。它带来了属性钩子（Property Hooks）、非对称可见性（Asymmetric Visibility）、改进的 HTML5 解析器以及一批全新的数组函数。对于每一位 PHP 开发者来说，了解并掌握这些新特性，是跟上现代 PHP 生态发展的必要功课。&lt;/p&gt;&lt;p&gt;本文将逐一深入讲解 PHP 8.4 的核心新特性，并通过真实可运行的代码示例，帮助你快速在项目中落地应用。&lt;/p&gt;&lt;h2&gt;属性钩子（Property Hooks）：告别冗余 Getter/Setter&lt;/h2&gt;&lt;p&gt;属性钩子是 PHP 8.4 最受期待的特性之一。它允许开发者直接在属性声明中定义 &lt;code&gt;get&lt;/code&gt; 和 &lt;code&gt;set&lt;/code&gt; 逻辑，彻底告别以往冗长的 Getter/Setter 样板代码。&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;User&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;$name&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(string&amp;nbsp;$value)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(strlen($value)&amp;nbsp;&amp;lt;&amp;nbsp;2)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;\ValueError(&amp;#39;Name&amp;nbsp;must&amp;nbsp;be&amp;nbsp;at&amp;nbsp;least&amp;nbsp;2&amp;nbsp;characters.&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;name&amp;nbsp;=&amp;nbsp;ucfirst(trim($value));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;$this-&amp;gt;name&amp;nbsp;??&amp;nbsp;&amp;#39;Anonymous&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;$email&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(string&amp;nbsp;$value)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!filter_var($value,&amp;nbsp;FILTER_VALIDATE_EMAIL))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;\ValueError(&amp;#39;Invalid&amp;nbsp;email&amp;nbsp;address.&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;email&amp;nbsp;=&amp;nbsp;strtolower($value);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

$user&amp;nbsp;=&amp;nbsp;new&amp;nbsp;User();
$user-&amp;gt;name&amp;nbsp;=&amp;nbsp;&amp;#39;&amp;nbsp;&amp;nbsp;alice&amp;nbsp;&amp;nbsp;&amp;#39;;
echo&amp;nbsp;$user-&amp;gt;name;&amp;nbsp;//&amp;nbsp;输出:&amp;nbsp;Alice

$user-&amp;gt;email&amp;nbsp;=&amp;nbsp;&amp;#39;Alice@Example.COM&amp;#39;;
echo&amp;nbsp;$user-&amp;gt;email;&amp;nbsp;//&amp;nbsp;输出:&amp;nbsp;alice@example.com&lt;/pre&gt;&lt;p&gt;属性钩子支持 &lt;code&gt;get&lt;/code&gt;、&lt;code&gt;set&lt;/code&gt; 或两者同时定义。接口和抽象类也可以声明带钩子的属性，极大提升了代码的表达力与可维护性。&lt;/p&gt;&lt;h2&gt;非对称可见性（Asymmetric Visibility）：读写权限精细化控制&lt;/h2&gt;&lt;p&gt;以往在 PHP 中，如果想让某个属性对外只读、对内可写，必须借助私有属性 + 公开 Getter 的组合。PHP 8.4 引入了非对称可见性，允许为属性的读取和写入分别设置不同的访问级别。&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Order&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;private(set)&amp;nbsp;int&amp;nbsp;$id;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;protected(set)&amp;nbsp;string&amp;nbsp;$status&amp;nbsp;=&amp;nbsp;&amp;#39;pending&amp;#39;;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;__construct(int&amp;nbsp;$id)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;id&amp;nbsp;=&amp;nbsp;$id;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;confirm():&amp;nbsp;void&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;status&amp;nbsp;=&amp;nbsp;&amp;#39;confirmed&amp;#39;;&amp;nbsp;//&amp;nbsp;类内部可写
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

$order&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Order(1001);
echo&amp;nbsp;$order-&amp;gt;id;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;可读：1001
echo&amp;nbsp;$order-&amp;gt;status;&amp;nbsp;//&amp;nbsp;可读：pending

//&amp;nbsp;$order-&amp;gt;id&amp;nbsp;=&amp;nbsp;9999;&amp;nbsp;//&amp;nbsp;报错！外部不可写
$order-&amp;gt;confirm();
echo&amp;nbsp;$order-&amp;gt;status;&amp;nbsp;//&amp;nbsp;confirmed&lt;/pre&gt;&lt;p&gt;语法格式为 &lt;code&gt;public private(set) Type $property&lt;/code&gt;，其中 &lt;code&gt;private(set)&lt;/code&gt; 表示只有类内部可以修改该属性，而读取权限则遵循 &lt;code&gt;public&lt;/code&gt; 声明。支持 &lt;code&gt;public&lt;/code&gt;、&lt;code&gt;protected&lt;/code&gt;、&lt;code&gt;private&lt;/code&gt; 的任意组合，让数据封装更加优雅。&lt;/p&gt;&lt;h2&gt;全新数组函数：array_find / array_find_key / array_any / array_all&lt;/h2&gt;&lt;p&gt;PHP 8.4 新增了四个实用数组函数，覆盖了开发中最常见的集合查找与判断场景，代码更简洁，意图更清晰。&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

$users&amp;nbsp;=&amp;nbsp;[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&amp;#39;name&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;Alice&amp;#39;,&amp;nbsp;&amp;#39;age&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;28,&amp;nbsp;&amp;#39;role&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;admin&amp;#39;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&amp;#39;name&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;Bob&amp;#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;age&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;22,&amp;nbsp;&amp;#39;role&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;user&amp;#39;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&amp;#39;name&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;Carol&amp;#39;,&amp;nbsp;&amp;#39;age&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;35,&amp;nbsp;&amp;#39;role&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;admin&amp;#39;],
];

//&amp;nbsp;array_find:&amp;nbsp;返回第一个满足条件的元素
$admin&amp;nbsp;=&amp;nbsp;array_find($users,&amp;nbsp;fn($u)&amp;nbsp;=&amp;gt;&amp;nbsp;$u[&amp;#39;role&amp;#39;]&amp;nbsp;===&amp;nbsp;&amp;#39;admin&amp;#39;);
//&amp;nbsp;[&amp;#39;name&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;Alice&amp;#39;,&amp;nbsp;&amp;#39;age&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;28,&amp;nbsp;&amp;#39;role&amp;#39;&amp;nbsp;=&amp;gt;&amp;nbsp;&amp;#39;admin&amp;#39;]

//&amp;nbsp;array_find_key:&amp;nbsp;返回第一个满足条件的键名
$key&amp;nbsp;=&amp;nbsp;array_find_key($users,&amp;nbsp;fn($u)&amp;nbsp;=&amp;gt;&amp;nbsp;$u[&amp;#39;age&amp;#39;]&amp;nbsp;&amp;gt;&amp;nbsp;30);
//&amp;nbsp;2

//&amp;nbsp;array_any:&amp;nbsp;是否存在至少一个满足条件的元素
$hasAdmin&amp;nbsp;=&amp;nbsp;array_any($users,&amp;nbsp;fn($u)&amp;nbsp;=&amp;gt;&amp;nbsp;$u[&amp;#39;role&amp;#39;]&amp;nbsp;===&amp;nbsp;&amp;#39;admin&amp;#39;);
//&amp;nbsp;true

//&amp;nbsp;array_all:&amp;nbsp;是否所有元素都满足条件
$allAdult&amp;nbsp;=&amp;nbsp;array_all($users,&amp;nbsp;fn($u)&amp;nbsp;=&amp;gt;&amp;nbsp;$u[&amp;#39;age&amp;#39;]&amp;nbsp;&amp;gt;=&amp;nbsp;18);
//&amp;nbsp;true

echo&amp;nbsp;&amp;quot;管理员:&amp;nbsp;{$admin[&amp;#39;name&amp;#39;]}\n&amp;quot;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Alice
echo&amp;nbsp;&amp;quot;索引大于30岁:&amp;nbsp;$key\n&amp;quot;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;2
echo&amp;nbsp;&amp;quot;有管理员:&amp;nbsp;&amp;quot;&amp;nbsp;.&amp;nbsp;($hasAdmin&amp;nbsp;?&amp;nbsp;&amp;#39;Y&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;N&amp;#39;)&amp;nbsp;.&amp;nbsp;&amp;quot;\n&amp;quot;;&amp;nbsp;//&amp;nbsp;Y
echo&amp;nbsp;&amp;quot;全成年:&amp;nbsp;&amp;quot;&amp;nbsp;.&amp;nbsp;($allAdult&amp;nbsp;?&amp;nbsp;&amp;#39;Y&amp;#39;&amp;nbsp;:&amp;nbsp;&amp;#39;N&amp;#39;)&amp;nbsp;.&amp;nbsp;&amp;quot;\n&amp;quot;;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Y&lt;/pre&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;array_find&lt;/strong&gt;：找到第一个满足回调的元素，找不到返回 &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;array_find_key&lt;/strong&gt;：找到第一个满足回调的元素的键，找不到返回 &lt;code&gt;null&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;array_any&lt;/strong&gt;：至少一个元素满足回调则返回 &lt;code&gt;true&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;array_all&lt;/strong&gt;：所有元素均满足回调则返回 &lt;code&gt;true&lt;/code&gt;，空数组也返回 &lt;code&gt;true&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;更多实用改进：new 不加括号、HTML5 解析器、#[\Deprecated] 注解&lt;/h2&gt;&lt;p&gt;除了以上三大主角，PHP 8.4 还带来了多项细节改进，让日常开发更顺手：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;new 不加括号直接链式调用&lt;/strong&gt;：以往 &lt;code&gt;(new Foo())-&amp;gt;bar()&lt;/code&gt; 必须加括号，8.4 起可直接写 &lt;code&gt;new Foo()-&amp;gt;bar()&lt;/code&gt;，代码更流畅。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;全新 HTML5 解析器&lt;/strong&gt;：&lt;code&gt;Dom\HTMLDocument::createFromString()&lt;/code&gt; 基于 Lexbor 引擎，完全符合 HTML5 规范，彻底解决旧版 &lt;code&gt;DOMDocument&lt;/code&gt; 解析现代 HTML 时的各类问题。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;#[\Deprecated] 注解&lt;/strong&gt;：开发者可以通过 &lt;code&gt;#[\Deprecated(message: &amp;#39;...&amp;#39;, since: &amp;#39;2.0&amp;#39;)]&lt;/code&gt; 为自定义函数和方法标记废弃，触发 &lt;code&gt;E_USER_DEPRECATED&lt;/code&gt;，与内置函数的废弃提示保持一致。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;BCMath 对象 API&lt;/strong&gt;：&lt;code&gt;BcMath\Number&lt;/code&gt; 类支持运算符重载，高精度数学计算终于可以像普通数字一样书写表达式。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&amp;lt;?php

//&amp;nbsp;new&amp;nbsp;不加括号
$length&amp;nbsp;=&amp;nbsp;new&amp;nbsp;DateTime(&amp;#39;2024-11-21&amp;#39;)-&amp;gt;diff(new&amp;nbsp;DateTime())-&amp;gt;days;

//&amp;nbsp;HTML5&amp;nbsp;解析器
$doc&amp;nbsp;=&amp;nbsp;\Dom\HTMLDocument::createFromString(&amp;#39;Hello&amp;nbsp;PHP&amp;nbsp;8.4!&amp;#39;);
echo&amp;nbsp;$doc-&amp;gt;querySelector(&amp;#39;b&amp;#39;)-&amp;gt;textContent;&amp;nbsp;//&amp;nbsp;PHP&amp;nbsp;8.4

//&amp;nbsp;Deprecated&amp;nbsp;注解
#[\Deprecated(message:&amp;nbsp;&amp;#39;Use&amp;nbsp;newMethod()&amp;nbsp;instead&amp;#39;,&amp;nbsp;since:&amp;nbsp;&amp;#39;2.0&amp;#39;)]
function&amp;nbsp;oldMethod():&amp;nbsp;void&amp;nbsp;{}

oldMethod();&amp;nbsp;//&amp;nbsp;触发&amp;nbsp;E_DEPRECATED&amp;nbsp;提示&lt;/pre&gt;&lt;h2&gt;升级建议与兼容性注意事项&lt;/h2&gt;&lt;p&gt;PHP 8.4 在向后兼容性方面总体表现良好，但仍有以下几点需要关注：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;隐式可空类型参数弃用&lt;/strong&gt;：&lt;code&gt;function foo(string $x = null)&lt;/code&gt; 在 8.4 中将触发弃用警告，需改为 &lt;code&gt;function foo(?string $x = null)&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;GMP 对象不再继承 stdClass&lt;/strong&gt;：若有依赖此行为的代码，需要调整。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;扩展兼容性&lt;/strong&gt;：部分 PECL 扩展需要更新到支持 PHP 8.4 的版本，建议在升级前通过 &lt;code&gt;composer check-platform-reqs&lt;/code&gt; 检查依赖。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;推荐升级路径&lt;/strong&gt;：建议先在测试/预发环境执行 &lt;code&gt;php -d error_reporting=E_ALL&lt;/code&gt; 跑完所有单元测试，修复所有 Deprecated 提示后，再上线正式环境。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;PHP 8.4 代表了 PHP 向现代语言演进的坚实一步。属性钩子和非对称可见性让面向对象编程更加优雅，新数组函数让集合操作更加直观，HTML5 解析器则彻底解决了困扰开发者多年的痛点。现在正是拥抱 PHP 8.4 的最佳时机。&lt;/p&gt;</description><pubDate>Fri, 17 Jul 2026 08:09:36 +0800</pubDate></item><item><title>Jetpack Compose 动画实战：从基础 API 到性能优化全解析</title><link>https://blog.resmic.cn/post/326.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260716080549178416034984391.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;为什么选择 Jetpack Compose 动画系统？&lt;/h2&gt;&lt;p&gt;传统 Android 动画（Property Animator、ViewPropertyAnimator）需要大量样板代码，与 View 体系高度耦合。Jetpack Compose 的动画系统从设计之初就与声明式 UI 深度集成，让动画与状态变化自然绑定，代码量减少 60% 以上，同时获得更好的可组合性与可测试性。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;声明式动画：动画跟随状态自动触发，无需手动启动/停止&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;协程原生支持：通过 &lt;code&gt;suspend&lt;/code&gt; 函数控制动画时序&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;低 GC 压力：基于 &lt;code&gt;State&lt;/code&gt; 的更新路径，减少对象分配&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;开箱即用的物理动画：弹簧（spring）、衰减（decay）效果内置支持&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;核心 API 速览：从简单到复杂&lt;/h2&gt;&lt;p&gt;Compose 动画 API 分为高级 API 和低级 API 两层，理解各自的适用场景是掌握动画系统的关键。&lt;/p&gt;&lt;h3&gt;高级 API&lt;/h3&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;animateContentSize&lt;/strong&gt;：Modifier 级别的尺寸变化动画，一行代码搞定&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;AnimatedVisibility&lt;/strong&gt;：控制组件的显示/隐藏，支持自定义进出场动画&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;AnimatedContent&lt;/strong&gt;：内容切换时的过渡动画，支持 &lt;code&gt;ContentTransform&lt;/code&gt; 自定义&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Crossfade&lt;/strong&gt;：简单的淡入淡出内容切换&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;AnimatedVisibility&amp;nbsp;示例
var&amp;nbsp;visible&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;mutableStateOf(true)&amp;nbsp;}

AnimatedVisibility(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;visible&amp;nbsp;=&amp;nbsp;visible,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enter&amp;nbsp;=&amp;nbsp;slideInVertically(initialOffsetY&amp;nbsp;=&amp;nbsp;{&amp;nbsp;-it&amp;nbsp;})&amp;nbsp;+&amp;nbsp;fadeIn(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;=&amp;nbsp;slideOutVertically(targetOffsetY&amp;nbsp;=&amp;nbsp;{&amp;nbsp;-it&amp;nbsp;})&amp;nbsp;+&amp;nbsp;fadeOut()
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Card(modifier&amp;nbsp;=&amp;nbsp;Modifier.fillMaxWidth().padding(16.dp))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(&amp;quot;我是动画卡片&amp;quot;,&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.padding(16.dp))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

Button(onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;visible&amp;nbsp;=&amp;nbsp;!visible&amp;nbsp;})&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(if&amp;nbsp;(visible)&amp;nbsp;&amp;quot;隐藏&amp;quot;&amp;nbsp;else&amp;nbsp;&amp;quot;显示&amp;quot;)
}&lt;/pre&gt;&lt;h3&gt;低级 API&lt;/h3&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;animate*AsState&lt;/strong&gt;：将普通值转换为动画值，如 &lt;code&gt;animateFloatAsState&lt;/code&gt;、&lt;code&gt;animateDpAsState&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;updateTransition&lt;/strong&gt;：管理多个动画值的状态机，适合多属性同步动画&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;rememberInfiniteTransition&lt;/strong&gt;：无限循环动画，适合加载指示器、呼吸灯效果&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Animatable&lt;/strong&gt;：命令式动画控制，与协程配合实现复杂时序&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;animate*AsState&amp;nbsp;示例：颜色与大小联动
var&amp;nbsp;selected&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;mutableStateOf(false)&amp;nbsp;}
val&amp;nbsp;bgColor&amp;nbsp;by&amp;nbsp;animateColorAsState(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetValue&amp;nbsp;=&amp;nbsp;if&amp;nbsp;(selected)&amp;nbsp;MaterialTheme.colorScheme.primaryContainer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;MaterialTheme.colorScheme.surface,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;tween(durationMillis&amp;nbsp;=&amp;nbsp;300)
)
val&amp;nbsp;scale&amp;nbsp;by&amp;nbsp;animateFloatAsState(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;targetValue&amp;nbsp;=&amp;nbsp;if&amp;nbsp;(selected)&amp;nbsp;1.05f&amp;nbsp;else&amp;nbsp;1.0f,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;spring(dampingRatio&amp;nbsp;=&amp;nbsp;Spring.DampingRatioMediumBouncy)
)

Box(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.scale(scale)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.background(bgColor,&amp;nbsp;RoundedCornerShape(12.dp))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.clickable&amp;nbsp;{&amp;nbsp;selected&amp;nbsp;=&amp;nbsp;!selected&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.padding(16.dp)
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Text(&amp;quot;点我试试&amp;quot;,&amp;nbsp;style&amp;nbsp;=&amp;nbsp;MaterialTheme.typography.bodyLarge)
}&lt;/pre&gt;&lt;h2&gt;实战场景一：列表项进场动画&lt;/h2&gt;&lt;p&gt;列表是 Android 应用中最常见的 UI 形态，为列表项添加错落进场动画可以显著提升用户感知质量。以下是基于 LazyColumn 实现的交错动画方案：&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;AnimatedListItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;index:&amp;nbsp;Int,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier:&amp;nbsp;Modifier&amp;nbsp;=&amp;nbsp;Modifier
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var&amp;nbsp;visible&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{&amp;nbsp;mutableStateOf(false)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LaunchedEffect(Unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delay(index&amp;nbsp;*&amp;nbsp;50L)&amp;nbsp;//&amp;nbsp;错落延迟
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;visible&amp;nbsp;=&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AnimatedVisibility(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;visible&amp;nbsp;=&amp;nbsp;visible,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;enter&amp;nbsp;=&amp;nbsp;fadeIn(tween(300))&amp;nbsp;+&amp;nbsp;slideInHorizontally(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animationSpec&amp;nbsp;=&amp;nbsp;tween(300,&amp;nbsp;easing&amp;nbsp;=&amp;nbsp;FastOutSlowInEasing),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;initialOffsetX&amp;nbsp;=&amp;nbsp;{&amp;nbsp;it&amp;nbsp;/&amp;nbsp;2&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ListItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;headlineContent&amp;nbsp;=&amp;nbsp;{&amp;nbsp;Text(item)&amp;nbsp;},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.fillMaxWidth()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.padding(horizontal&amp;nbsp;=&amp;nbsp;16.dp,&amp;nbsp;vertical&amp;nbsp;=&amp;nbsp;4.dp)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

@Composable
fun&amp;nbsp;AnimatedLazyList(items:&amp;nbsp;List&amp;lt;String&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;itemsIndexed(items)&amp;nbsp;{&amp;nbsp;index,&amp;nbsp;item&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AnimatedListItem(item&amp;nbsp;=&amp;nbsp;item,&amp;nbsp;index&amp;nbsp;=&amp;nbsp;index)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;注意：&lt;code&gt;LaunchedEffect(Unit)&lt;/code&gt; 确保动画只在组件首次进入组合时触发，避免重组时重复播放。&lt;/p&gt;&lt;h2&gt;实战场景二：共享元素过渡（Compose 1.7+）&lt;/h2&gt;&lt;p&gt;共享元素过渡（Shared Element Transition）是 Material 3 设计语言中的核心体验，Compose 1.7 正式稳定了这一 API。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;在&amp;nbsp;SharedTransitionLayout&amp;nbsp;内使用
@Composable
fun&amp;nbsp;SharedTransitionLayout(content:&amp;nbsp;@Composable&amp;nbsp;SharedTransitionScope.()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;官方&amp;nbsp;API，需要&amp;nbsp;androidx.compose.animation&amp;nbsp;1.7+
}

//&amp;nbsp;列表页
@Composable
fun&amp;nbsp;SharedTransitionScope.ThumbnailItem(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;item:&amp;nbsp;PhotoItem,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animatedVisibilityScope:&amp;nbsp;AnimatedVisibilityScope,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;onClick:&amp;nbsp;()&amp;nbsp;-&amp;gt;&amp;nbsp;Unit
)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Image(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;painter&amp;nbsp;=&amp;nbsp;rememberAsyncImagePainter(item.url),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentDescription&amp;nbsp;=&amp;nbsp;null,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.sharedElement(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;state&amp;nbsp;=&amp;nbsp;rememberSharedContentState(key&amp;nbsp;=&amp;nbsp;&amp;quot;image-${item.id}&amp;quot;),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;animatedVisibilityScope&amp;nbsp;=&amp;nbsp;animatedVisibilityScope
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.size(80.dp)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.clip(RoundedCornerShape(8.dp))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.clickable(onClick&amp;nbsp;=&amp;nbsp;onClick)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
}

//&amp;nbsp;详情页使用相同的&amp;nbsp;key&amp;nbsp;即可实现平滑过渡&lt;/pre&gt;&lt;h2&gt;性能优化：避免过度重组&lt;/h2&gt;&lt;p&gt;动画性能问题往往源于不必要的重组（Recomposition）。以下是经过实践验证的优化策略：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;使用 derivedStateOf&lt;/strong&gt;：当动画值被多个 Composable 读取时，用 &lt;code&gt;derivedStateOf&lt;/code&gt; 减少传播范围&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;lambda 下沉&lt;/strong&gt;：将读取动画状态的代码下沉到 Modifier lambda 中，只触发 Layout/Draw 阶段而非整个重组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;避免在动画中读取非稳定对象&lt;/strong&gt;：确保数据类实现 &lt;code&gt;@Stable&lt;/code&gt; 或使用 &lt;code&gt;@Immutable&lt;/code&gt; 标注&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;使用 graphicsLayer&lt;/strong&gt;：平移、旋转、缩放等变换通过 &lt;code&gt;graphicsLayer&lt;/code&gt; 实现，绕过 Layout 阶段直接走 Draw&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;✅&amp;nbsp;推荐：lambda&amp;nbsp;下沉，只触发&amp;nbsp;graphicsLayer&amp;nbsp;重绘
val&amp;nbsp;scale&amp;nbsp;by&amp;nbsp;animateFloatAsState(targetValue&amp;nbsp;=&amp;nbsp;targetScale)

Box(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modifier&amp;nbsp;=&amp;nbsp;Modifier.graphicsLayer&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scaleX&amp;nbsp;=&amp;nbsp;scale&amp;nbsp;&amp;nbsp;//&amp;nbsp;在&amp;nbsp;lambda&amp;nbsp;内读取，不触发外部重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;scaleY&amp;nbsp;=&amp;nbsp;scale
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
)

//&amp;nbsp;❌&amp;nbsp;避免：在外部读取，导致整个&amp;nbsp;Box&amp;nbsp;重组
Box(modifier&amp;nbsp;=&amp;nbsp;Modifier.scale(scale))&amp;nbsp;//&amp;nbsp;每帧都重组&lt;/pre&gt;&lt;p&gt;通过 Layout Inspector 的 Recomposition 高亮功能可以直观发现热点区域，配合 Compose 编译器指标报告（&lt;code&gt;freeCompilerArgs += &amp;quot;-P&amp;quot;, &amp;quot;plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=...&amp;quot;&lt;/code&gt;）可以系统性地优化整个界面的重组效率。&lt;/p&gt;</description><pubDate>Thu, 16 Jul 2026 08:07:46 +0800</pubDate></item><item><title>Prompt Engineering 完全指南：从零到精通的提示词工程实战</title><link>https://blog.resmic.cn/post/325.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260715080416178407385691658.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;一、什么是 Prompt Engineering？&lt;/h2&gt;&lt;p&gt;Prompt Engineering（提示词工程）是指通过精心设计输入文本，引导大语言模型（LLM）输出更准确、更符合预期结果的一门技术。随着 GPT-4、Claude 3、Gemini 1.5 等强大模型的普及，Prompt Engineering 已经成为 AI 应用开发者必须掌握的核心技能。&lt;/p&gt;&lt;p&gt;一个好的提示词能让模型从&amp;quot;差不多能用&amp;quot;变成&amp;quot;精准好用&amp;quot;，而一个糟糕的提示词则可能让即便是最强的模型也输出废话。本文将系统梳理 2025 年最实用的提示词工程技巧，结合真实业务场景，帮你构建自己的提示词工程体系。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;指令跟随能力&lt;/strong&gt;：模型理解并执行明确指令的能力&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;上下文理解&lt;/strong&gt;：模型利用上下文信息推断意图的能力&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;格式控制&lt;/strong&gt;：引导模型输出结构化、可解析的内容&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;行为约束&lt;/strong&gt;：限制模型的输出范围，避免幻觉和越界&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;二、基础技巧：角色设定与任务分解&lt;/h2&gt;&lt;p&gt;角色设定（Role Prompting）是最基础也是最有效的技巧之一。通过在 System Prompt 中明确模型的角色，可以大幅提升输出质量和一致性。&lt;/p&gt;&lt;pre&gt;#&amp;nbsp;示例：代码审查助手角色设定
system_prompt&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
你是一位拥有10年经验的高级软件工程师，专注于代码质量和安全审查。
你的职责是：
1.&amp;nbsp;识别代码中的潜在安全漏洞（SQL注入、XSS、CSRF等）
2.&amp;nbsp;指出性能瓶颈和优化建议
3.&amp;nbsp;检查代码规范和可维护性问题
4.&amp;nbsp;用简洁、专业的语言给出修改建议

输出格式：
-&amp;nbsp;问题描述（一句话）
-&amp;nbsp;风险等级（高/中/低）
-&amp;nbsp;修改建议（带代码示例）
&amp;quot;&amp;quot;&amp;quot;&lt;/pre&gt;&lt;p&gt;任务分解则是将复杂任务拆分为多个子步骤，每次只要求模型完成一个明确的子任务。研究表明，任务分解可以将复杂任务的准确率提升 30%-50%。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;串行分解&lt;/strong&gt;：步骤1完成后，将结果作为步骤2的输入&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;并行分解&lt;/strong&gt;：多个子任务同时执行，最后汇总结果&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;递归分解&lt;/strong&gt;：将大问题不断拆分直到每个子问题都可直接解决&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;三、进阶技巧：思维链（Chain of Thought）&lt;/h2&gt;&lt;p&gt;思维链（CoT）提示是 Google 研究团队在 2022 年提出的突破性技术，通过在提示词中加入&amp;quot;让我们一步步思考&amp;quot;或展示推理过程的示例，可以显著提升模型在数学推理、逻辑推断等复杂任务上的表现。&lt;/p&gt;&lt;pre&gt;#&amp;nbsp;Zero-shot&amp;nbsp;CoT：直接触发思维链
prompt&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
问题：一家工厂每天生产1500个零件，其中5%是次品，次品中有30%可以返工修复。
每天实际可用的合格零件数量是多少？

请一步步思考，然后给出最终答案。
&amp;quot;&amp;quot;&amp;quot;

#&amp;nbsp;Few-shot&amp;nbsp;CoT：通过示例引导推理模式
prompt&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
示例问题：小明有20块糖，给了小红1/4，又买了10块，现在有多少块？
推理：20&amp;nbsp;×&amp;nbsp;(1-1/4)&amp;nbsp;=&amp;nbsp;15块，15&amp;nbsp;+&amp;nbsp;10&amp;nbsp;=&amp;nbsp;25块。答案：25块。

现在解决：[你的问题]
推理：[模型会自动跟随这个格式]
&amp;quot;&amp;quot;&amp;quot;&lt;/pre&gt;&lt;p&gt;2024年兴起的 &lt;strong&gt;Tree of Thought（ToT）&lt;/strong&gt; 更进一步，让模型生成多条思维路径，通过评估选择最优路径，在复杂问题上比标准 CoT 准确率高出 74%。&lt;/p&gt;&lt;h2&gt;四、Few-shot 与 RAG 的结合使用&lt;/h2&gt;&lt;p&gt;Few-shot Learning（少样本学习）通过在提示词中提供2-5个精选示例，帮助模型理解任务的输入输出格式和质量标准。关键是示例的选择策略：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;多样性覆盖&lt;/strong&gt;：示例应覆盖典型情况、边界情况和易错情况&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;相关性优先&lt;/strong&gt;：使用与当前查询语义最相近的示例&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;质量把关&lt;/strong&gt;：示例本身必须是正确的高质量输出&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;动态选择&lt;/strong&gt;：结合 RAG 根据当前输入动态选择最相关的示例&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;#&amp;nbsp;动态Few-shot&amp;nbsp;+&amp;nbsp;RAG&amp;nbsp;示例选择
from&amp;nbsp;sentence_transformers&amp;nbsp;import&amp;nbsp;SentenceTransformer
import&amp;nbsp;numpy&amp;nbsp;as&amp;nbsp;np

def&amp;nbsp;select_few_shot_examples(query,&amp;nbsp;example_pool,&amp;nbsp;k=3):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;基于语义相似度动态选择Few-shot示例&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;model&amp;nbsp;=&amp;nbsp;SentenceTransformer(&amp;#39;all-MiniLM-L6-v2&amp;#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;query_emb&amp;nbsp;=&amp;nbsp;model.encode([query])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;example_embs&amp;nbsp;=&amp;nbsp;model.encode([ex[&amp;#39;input&amp;#39;]&amp;nbsp;for&amp;nbsp;ex&amp;nbsp;in&amp;nbsp;example_pool])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;similarities&amp;nbsp;=&amp;nbsp;np.dot(query_emb,&amp;nbsp;example_embs.T)[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;top_k_idx&amp;nbsp;=&amp;nbsp;np.argsort(similarities)[-k:][::-1]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;[example_pool[i]&amp;nbsp;for&amp;nbsp;i&amp;nbsp;in&amp;nbsp;top_k_idx]

#&amp;nbsp;构建动态提示词
selected&amp;nbsp;=&amp;nbsp;select_few_shot_examples(user_query,&amp;nbsp;example_pool)
prompt&amp;nbsp;=&amp;nbsp;build_prompt_with_examples(selected,&amp;nbsp;user_query)&lt;/pre&gt;&lt;h2&gt;五、自洽性校验与输出稳定性优化&lt;/h2&gt;&lt;p&gt;LLM 的输出具有随机性，同一个问题可能得到不同答案。自洽性校验（Self-Consistency）通过多次采样然后投票选择最一致的答案，可以显著提升稳定性。&lt;/p&gt;&lt;pre&gt;import&amp;nbsp;anthropic
from&amp;nbsp;collections&amp;nbsp;import&amp;nbsp;Counter

def&amp;nbsp;self_consistent_answer(prompt,&amp;nbsp;n_samples=5,&amp;nbsp;model=&amp;quot;claude-3-5-sonnet-20241022&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;自洽性校验：多次采样投票&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;client&amp;nbsp;=&amp;nbsp;anthropic.Anthropic()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;answers&amp;nbsp;=&amp;nbsp;[]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;_&amp;nbsp;in&amp;nbsp;range(n_samples):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response&amp;nbsp;=&amp;nbsp;client.messages.create(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;model=model,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;max_tokens=1024,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;messages=[{&amp;quot;role&amp;quot;:&amp;nbsp;&amp;quot;user&amp;quot;,&amp;nbsp;&amp;quot;content&amp;quot;:&amp;nbsp;prompt}]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;提取关键答案（此处需根据实际格式解析）
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;answer&amp;nbsp;=&amp;nbsp;extract_final_answer(response.content[0].text)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;answers.append(answer)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;投票选最多的答案
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;most_common&amp;nbsp;=&amp;nbsp;Counter(answers).most_common(1)[0][0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;confidence&amp;nbsp;=&amp;nbsp;answers.count(most_common)&amp;nbsp;/&amp;nbsp;n_samples
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;most_common,&amp;nbsp;confidence

answer,&amp;nbsp;conf&amp;nbsp;=&amp;nbsp;self_consistent_answer(&amp;quot;你的问题&amp;quot;)
print(f&amp;quot;答案：{answer}，置信度：{conf:.0%}&amp;quot;)&lt;/pre&gt;&lt;p&gt;除自洽性校验外，以下技巧也能提升输出稳定性：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;温度控制&lt;/strong&gt;：对需要确定性答案的任务，将 temperature 设为 0&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;输出格式约束&lt;/strong&gt;：要求 JSON、XML 等结构化格式，便于解析和校验&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;负面约束&lt;/strong&gt;：明确告知模型&amp;quot;不要做什么&amp;quot;，减少不期望的行为&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;自我反思&lt;/strong&gt;：让模型先生成答案，再检查并修正，类似 Reflection 模式&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;六、针对不同模型的调优策略&lt;/h2&gt;&lt;p&gt;不同大模型有各自的特点和最佳实践，了解这些差异能让你的提示词事半功倍：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;GPT-4o&lt;/strong&gt;：擅长遵循详细指令，支持 JSON Mode，System Prompt 效果显著&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Claude 3.5/4&lt;/strong&gt;：对 XML 标签格式友好，长文档理解能力强，适合复杂推理&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gemini 1.5 Pro&lt;/strong&gt;：100万 token 超长上下文，适合大文档分析和多轮对话&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Llama 3 / Qwen2.5&lt;/strong&gt;：开源模型对提示词格式更敏感，需严格遵循官方模板&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;#&amp;nbsp;Claude&amp;nbsp;XML格式提示词示例
prompt&amp;nbsp;=&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;
&amp;lt;task&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;role&amp;gt;你是一个专业的数据分析师&amp;lt;/role&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;input&amp;gt;{user_data}&amp;lt;/input&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;requirements&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;item&amp;gt;识别数据中的趋势和异常&amp;lt;/item&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;item&amp;gt;生成可执行的业务建议&amp;lt;/item&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;item&amp;gt;输出格式为JSON&amp;lt;/item&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/requirements&amp;gt;
&amp;lt;/task&amp;gt;
&amp;quot;&amp;quot;&amp;quot;&lt;/pre&gt;&lt;h2&gt;七、提示词工程的工程化实践&lt;/h2&gt;&lt;p&gt;在生产环境中，提示词需要像代码一样被管理和迭代。以下是构建提示词工程体系的最佳实践：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;版本控制&lt;/strong&gt;：将提示词存入 Git，记录每次变更和效果数据&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;A/B 测试&lt;/strong&gt;：同时运行多版本提示词，通过数据决定使用哪个&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;评估集&lt;/strong&gt;：建立100-500条标注数据，用于量化评估提示词效果&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;监控告警&lt;/strong&gt;：对输出质量进行实时监控，输出异常时自动告警&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;提示词库&lt;/strong&gt;：沉淀经过验证的提示词模板，供团队复用&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;推荐工具链：&lt;strong&gt;LangSmith&lt;/strong&gt;（提示词追踪与评估）、&lt;strong&gt;PromptFlow&lt;/strong&gt;（提示词流程编排）、&lt;strong&gt;Promptfoo&lt;/strong&gt;（开源提示词测试框架）。掌握这些工具，才能让提示词工程真正落地到业务系统中。&lt;/p&gt;&lt;p&gt;总结来说，Prompt Engineering 不是玄学，而是有规律可循的工程技能。从角色设定到思维链，从 Few-shot 到自洽性校验，每一个技巧背后都有坚实的研究支撑。希望本文能帮助你系统构建提示词工程能力，在 AI 应用开发中事半功倍。&lt;/p&gt;</description><pubDate>Wed, 15 Jul 2026 08:06:34 +0800</pubDate></item><item><title>Android Jetpack Compose 性能优化实战：从原理到实践</title><link>https://blog.resmic.cn/post/324.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260714080614178398757454420.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;为什么 Compose 需要性能优化&lt;/h2&gt;&lt;p&gt;Jetpack Compose 自 2021 年正式发布以来，已成为 Android UI 开发的首选方案。然而，许多开发者在项目规模扩大后开始遇到界面卡顿、帧率下降等问题。这些问题的根源往往在于对 Compose &lt;strong&gt;重组（Recomposition）机制&lt;/strong&gt;理解不足，导致不必要的重绘操作。&lt;/p&gt;&lt;p&gt;根据 Google 官方 Compose 性能指南，一个流畅的 Android 应用需要在 16ms 内完成每帧渲染（60fps），而 Compose 中频繁的重组会大量消耗这一预算。理解并掌握重组优化技术，是每位 Compose 开发者的必修课。&lt;/p&gt;&lt;h2&gt;深入理解重组机制&lt;/h2&gt;&lt;p&gt;Compose 采用&lt;strong&gt;响应式编程模型&lt;/strong&gt;，当 State 发生变化时，读取该 State 的 Composable 函数会被重新执行，这个过程称为重组。理解以下几个核心概念至关重要：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Composition&lt;/strong&gt;：首次执行所有 Composable 函数，构建 UI 树的过程&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recomposition&lt;/strong&gt;：State 变化后，仅重新执行受影响的 Composable 函数&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stable 与 Unstable 类型&lt;/strong&gt;：Compose 编译器会分析参数类型是否稳定，不稳定类型会导致强制重组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;智能重组跳过&lt;/strong&gt;：若所有参数均未变化，Compose 会自动跳过该函数的重组&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;一个常见误区是认为 Compose 会自动优化一切。实际上，如果你的数据类没有正确实现 &lt;code&gt;equals()&lt;/code&gt;，或者使用了 List、Map 等不稳定集合类型，Compose 将无法判断数据是否真正变化，从而触发不必要的重组。&lt;/p&gt;&lt;h2&gt;关键优化技巧：remember 与 derivedStateOf&lt;/h2&gt;&lt;p&gt;&lt;code&gt;remember&lt;/code&gt; 是 Compose 中避免重复计算的核心 API。配合 &lt;code&gt;derivedStateOf&lt;/code&gt;，可以大幅减少无效的重组触发。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;错误用法：每次重组都重新创建&amp;nbsp;list，导致下游重组
@Composable
fun&amp;nbsp;BadExample(items:&amp;nbsp;List&amp;lt;String&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;filtered&amp;nbsp;=&amp;nbsp;items.filter&amp;nbsp;{&amp;nbsp;it.isNotEmpty()&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;每次重组都执行
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(filtered)&amp;nbsp;{&amp;nbsp;Text(it)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;✅&amp;nbsp;正确用法：用&amp;nbsp;derivedStateOf&amp;nbsp;包装计算逻辑
@Composable
fun&amp;nbsp;GoodExample(items:&amp;nbsp;List&amp;lt;String&amp;gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;filtered&amp;nbsp;by&amp;nbsp;remember(items)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;derivedStateOf&amp;nbsp;{&amp;nbsp;items.filter&amp;nbsp;{&amp;nbsp;it.isNotEmpty()&amp;nbsp;}&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(filtered)&amp;nbsp;{&amp;nbsp;Text(it)&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;&lt;code&gt;derivedStateOf&lt;/code&gt; 的关键优势在于：只有当计算结果真正发生变化时，才会触发依赖它的 Composable 重组。这在处理列表过滤、排序等场景下尤为重要。&lt;/p&gt;&lt;p&gt;此外，&lt;code&gt;remember&lt;/code&gt; 的 key 参数同样不可忽视。不传 key 意味着仅在首次组合时计算，传入 key 意味着 key 变化时重新计算：&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;key&amp;nbsp;变化时重新计算
val&amp;nbsp;result&amp;nbsp;=&amp;nbsp;remember(userId)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;expensiveCalculation(userId)
}&lt;/pre&gt;&lt;h2&gt;LazyColumn 性能优化实战&lt;/h2&gt;&lt;p&gt;LazyColumn 是 Compose 中最常用的列表组件，也是性能问题的高发区。以下是几个经过验证的优化手段：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;稳定的 key 参数&lt;/strong&gt;：为每个列表项提供唯一稳定的 key，避免因列表顺序变化引发全量重组&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;使用 contentType&lt;/strong&gt;：当列表包含多种 item 类型时，指定 contentType 提升 item 复用率&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;避免在 item lambda 中创建对象&lt;/strong&gt;：将 lambda 提升到 Composable 外部，防止重组时重复创建&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;图片加载懒加载&lt;/strong&gt;：结合 Coil 的 AsyncImage，避免列表滚动时同步加载图片&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;userList,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;user&amp;nbsp;-&amp;gt;&amp;nbsp;user.id&amp;nbsp;},&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;稳定的&amp;nbsp;key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contentType&amp;nbsp;=&amp;nbsp;{&amp;nbsp;user&amp;nbsp;-&amp;gt;&amp;nbsp;user.type&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;提升复用率
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;user&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UserCard(user&amp;nbsp;=&amp;nbsp;user)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;值得注意的是，在 items lambda 中尽量使用 &lt;code&gt;@Stable&lt;/code&gt; 或 &lt;code&gt;@Immutable&lt;/code&gt; 注解的数据类，这能显著提升 Compose 编译器的优化能力：&lt;/p&gt;&lt;pre&gt;@Immutable
data&amp;nbsp;class&amp;nbsp;User(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;id:&amp;nbsp;Long,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;name:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;avatar:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;type:&amp;nbsp;UserType
)&lt;/pre&gt;&lt;h2&gt;使用工具定位性能瓶颈&lt;/h2&gt;&lt;p&gt;优化的前提是精准定位问题。Android Studio 提供了两个强大的 Compose 性能分析工具：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layout Inspector&lt;/strong&gt;：实时查看 Composable 树结构，统计每个节点的重组次数和跳过次数&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recomposition Highlighter&lt;/strong&gt;：在 &lt;code&gt;local.properties&lt;/code&gt; 中加入 &lt;code&gt;compose.recompositionHighlighter=true&lt;/code&gt;，发生重组的区域会在界面上高亮显示，一目了然&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;结合 Android Profiler 的 CPU Trace 功能，可以精准找到每帧渲染中耗时最长的 Composable 函数，从而有针对性地进行优化。实践证明，仅仅通过修复几个高频重组的 Composable，就能将列表滚动帧率从 45fps 提升到稳定的 60fps。&lt;/p&gt;&lt;p&gt;总结来说，Compose 性能优化的核心思路是：&lt;strong&gt;减少不必要的重组、缓存计算结果、提供稳定的数据类型&lt;/strong&gt;。掌握这些技巧，你的 Compose 应用将拥有媲美原生 View 系统的流畅体验。&lt;/p&gt;</description><pubDate>Tue, 14 Jul 2026 08:06:32 +0800</pubDate></item><item><title>Qwen3深度解析：混合思维模式与MoE架构带来的AI新突破</title><link>https://blog.resmic.cn/post/323.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260713080347178390102752223.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;Qwen3 横空出世：阿里云大模型的新里程碑&lt;/h2&gt;&lt;p&gt;2025年以来，大语言模型赛道竞争日趋白热化。阿里云适时推出 Qwen3 系列模型，以其卓越的推理能力和高效的架构设计，迅速引发业界广泛关注。Qwen3 不仅在多项权威基准测试中刷新记录，更在实际业务场景中展现出远超前代的工程价值。&lt;/p&gt;&lt;p&gt;本文将从技术架构、核心特性、实战使用三个维度，全面解析 Qwen3 的能力边界与应用方法，帮助开发者快速上手这款强大的国产大模型。&lt;/p&gt;&lt;h2&gt;核心技术突破：混合思维模式（Hybrid Thinking）&lt;/h2&gt;&lt;p&gt;Qwen3 最具革命性的创新之一是引入了&lt;strong&gt;混合思维模式&lt;/strong&gt;。传统大模型在回答时要么直接输出（快思考），要么开启长链式推理（慢思考）。Qwen3 则允许用户在同一个模型中动态切换：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;快速模式（Non-thinking）&lt;/strong&gt;：直接生成答案，适合简单问答、文本改写、日常对话，延迟极低&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;思考模式（Thinking）&lt;/strong&gt;：触发深度推理链（Chain-of-Thought），适合数学证明、复杂代码调试、逻辑推断&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;自适应模式&lt;/strong&gt;：模型根据问题复杂度自动决定是否开启推理，兼顾速度与质量&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;在实际使用中，只需在 system prompt 或 API 参数中指定 &lt;code&gt;enable_thinking: true/false&lt;/code&gt; 即可控制模式切换，极大提升了模型的灵活性。&lt;/p&gt;&lt;pre&gt;from&amp;nbsp;openai&amp;nbsp;import&amp;nbsp;OpenAI

client&amp;nbsp;=&amp;nbsp;OpenAI(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;api_key=&amp;quot;YOUR_DASHSCOPE_API_KEY&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base_url=&amp;quot;https://dashscope.aliyuncs.com/compatible-mode/v1&amp;quot;
)

#&amp;nbsp;开启思考模式
response&amp;nbsp;=&amp;nbsp;client.chat.completions.create(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;model=&amp;quot;qwen3-235b-a22b&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;messages=[
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;quot;role&amp;quot;:&amp;nbsp;&amp;quot;user&amp;quot;,&amp;nbsp;&amp;quot;content&amp;quot;:&amp;nbsp;&amp;quot;用Python实现快速排序，并分析其时间复杂度&amp;quot;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;extra_body={&amp;quot;enable_thinking&amp;quot;:&amp;nbsp;True}
)

print(response.choices[0].message.content)&lt;/pre&gt;&lt;h2&gt;MoE 架构深度解析：专家路由如何提升效率&lt;/h2&gt;&lt;p&gt;Qwen3 旗舰版采用&lt;strong&gt;Mixture of Experts（MoE）&lt;/strong&gt;架构，以 235B 总参数、22B 激活参数的设计，实现了&amp;quot;大模型能力、中等模型成本&amp;quot;的突破。&lt;/p&gt;&lt;p&gt;其核心优势体现在以下几个方面：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;动态专家路由&lt;/strong&gt;：每个 token 只激活最相关的若干专家网络，推理 FLOPs 仅为同规模稠密模型的 1/10&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;精细化专家分工&lt;/strong&gt;：代码专家、数学专家、语言专家各司其职，领域能力更为突出&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;负载均衡训练&lt;/strong&gt;：采用辅助损失函数避免专家坍缩，所有专家均能得到充分训练&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;长上下文支持&lt;/strong&gt;：原生支持 128K context window，满足长文档理解需求&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;对于中小规模部署需求，Qwen3 还提供了 0.6B、1.7B、4B、8B、14B、32B 的稠密版本，可在消费级 GPU 上直接运行。&lt;/p&gt;&lt;h2&gt;实战上手：本地部署与 API 调用全流程&lt;/h2&gt;&lt;p&gt;Qwen3 已在 Hugging Face 和 ModelScope 全面开源，支持多种部署方式。以下以 Ollama 本地部署为例：&lt;/p&gt;&lt;pre&gt;#&amp;nbsp;安装&amp;nbsp;Ollama
curl&amp;nbsp;-fsSL&amp;nbsp;https://ollama.com/install.sh&amp;nbsp;|&amp;nbsp;sh

#&amp;nbsp;拉取&amp;nbsp;Qwen3&amp;nbsp;8B&amp;nbsp;模型
ollama&amp;nbsp;pull&amp;nbsp;qwen3:8b

#&amp;nbsp;启动对话（开启思考模式）
ollama&amp;nbsp;run&amp;nbsp;qwen3:8b&amp;nbsp;&amp;quot;/think&amp;nbsp;用简洁语言解释量子纠缠&amp;quot;&lt;/pre&gt;&lt;p&gt;通过 vLLM 部署生产级服务：&lt;/p&gt;&lt;pre&gt;pip&amp;nbsp;install&amp;nbsp;vllm

python&amp;nbsp;-m&amp;nbsp;vllm.entrypoints.openai.api_server&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--model&amp;nbsp;Qwen/Qwen3-8B&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--enable-reasoning&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--reasoning-parser&amp;nbsp;deepseek_r1&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--tensor-parallel-size&amp;nbsp;2&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--port&amp;nbsp;8000&lt;/pre&gt;&lt;p&gt;如果需要快速体验而不想本地部署，可直接使用阿里云 DashScope API，支持按量付费，旗舰模型每百万 token 费用极具竞争力。&lt;/p&gt;&lt;h2&gt;基准测试对比与适用场景推荐&lt;/h2&gt;&lt;p&gt;根据官方及第三方评测数据，Qwen3-235B-A22B 在以下方向表现突出：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;代码生成&lt;/strong&gt;：HumanEval 得分超越 GPT-4o，LiveCodeBench 排名全球前三&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;数学推理&lt;/strong&gt;：MATH-500 接近满分，AIME 2025 成绩优异&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;中文理解&lt;/strong&gt;：CMMLU、C-Eval 双双领跑，母语优势明显&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;多语言支持&lt;/strong&gt;：原生支持 119 种语言，无需额外微调&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;综合来看，Qwen3 最适合的应用场景包括：企业智能客服、代码辅助开发、长文档摘要与分析、多语言内容生成、RAG 知识库问答系统等。对于资源受限场景，推荐使用 8B 或 14B 版本，在保持较高能力的同时大幅降低部署成本。&lt;/p&gt;&lt;p&gt;随着 Qwen3 的持续迭代与生态完善，国产大模型正在多个赛道实现全面突破。无论是个人开发者还是企业团队，现在都是拥抱 Qwen3、构建 AI 原生应用的最佳时机。&lt;/p&gt;</description><pubDate>Mon, 13 Jul 2026 08:04:29 +0800</pubDate></item><item><title>PHP 8.3 新特性全面解析：类型化常量、只读克隆与 json_validate 实战指南</title><link>https://blog.resmic.cn/post/322.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260712080702178381482232778.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;PHP 8.3 的发布背景与升级意义&lt;/h2&gt;&lt;p&gt;PHP 8.3 于 2023 年 11 月正式发布，是 PHP 8.x 系列的最新稳定版本。相比 8.2，它在类型系统、语法糖以及性能优化方面都有显著提升。对于长期从事 PHP 开发的工程师来说，这些新特性不只是语法上的甜头，更是帮助团队写出更安全、更可维护代码的利器。&lt;/p&gt;&lt;p&gt;本文将从实际项目角度，逐一拆解 PHP 8.3 中最值得关注的新特性，并给出可直接落地的代码示例。&lt;/p&gt;&lt;h2&gt;类型化类常量（Typed Class Constants）&lt;/h2&gt;&lt;p&gt;PHP 8.3 之前，类常量没有类型约束，这意味着子类可以用任意类型覆盖父类常量，埋下运行时错误的隐患。现在，你可以为常量声明类型：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

interface&amp;nbsp;HasVersion&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;VERSION&amp;nbsp;=&amp;nbsp;&amp;#39;1.0.0&amp;#39;;
}

class&amp;nbsp;App&amp;nbsp;implements&amp;nbsp;HasVersion&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;string&amp;nbsp;VERSION&amp;nbsp;=&amp;nbsp;&amp;#39;2.5.1&amp;#39;;&amp;nbsp;//&amp;nbsp;必须是&amp;nbsp;string，否则报错
}

//&amp;nbsp;以下会抛出&amp;nbsp;Fatal&amp;nbsp;error
class&amp;nbsp;BadApp&amp;nbsp;implements&amp;nbsp;HasVersion&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;int&amp;nbsp;VERSION&amp;nbsp;=&amp;nbsp;999;&amp;nbsp;//&amp;nbsp;类型不匹配
}&lt;/pre&gt;&lt;p&gt;这一特性对于定义接口契约、防止子类误用常量非常有价值，尤其在大型框架或多人协作项目中能有效减少低级错误。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;支持所有标量类型：&lt;code&gt;string&lt;/code&gt;、&lt;code&gt;int&lt;/code&gt;、&lt;code&gt;float&lt;/code&gt;、&lt;code&gt;bool&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;支持 &lt;code&gt;array&lt;/code&gt;、&lt;code&gt;null&lt;/code&gt; 及联合类型&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;接口和 trait 中同样适用&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;只读属性的深克隆支持（Readonly Properties in Clone）&lt;/h2&gt;&lt;p&gt;PHP 8.2 引入了只读类（readonly class），但克隆时无法修改只读属性，这在值对象（Value Object）模式中非常不便。PHP 8.3 允许在 &lt;code&gt;__clone&lt;/code&gt; 方法中对只读属性重新赋值：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Money&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;__construct(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;readonly&amp;nbsp;int&amp;nbsp;$amount,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;readonly&amp;nbsp;string&amp;nbsp;$currency,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;withAmount(int&amp;nbsp;$newAmount):&amp;nbsp;static&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$clone&amp;nbsp;=&amp;nbsp;clone&amp;nbsp;$this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;PHP&amp;nbsp;8.3:&amp;nbsp;可以在&amp;nbsp;__clone&amp;nbsp;上下文外通过此方式修改
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;实际推荐写法：
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;new&amp;nbsp;static($newAmount,&amp;nbsp;$this-&amp;gt;currency);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

//&amp;nbsp;使用深克隆模式处理不可变对象
readonly&amp;nbsp;class&amp;nbsp;Point&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;__construct(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;float&amp;nbsp;$x,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;float&amp;nbsp;$y,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;float&amp;nbsp;$z,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;withX(float&amp;nbsp;$x):&amp;nbsp;static&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$clone&amp;nbsp;=&amp;nbsp;clone&amp;nbsp;$this;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;PHP&amp;nbsp;8.3&amp;nbsp;允许在&amp;nbsp;__clone&amp;nbsp;内修改&amp;nbsp;readonly&amp;nbsp;属性
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;$clone;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;这让不可变数据结构的实现变得更加自然，无需绕过只读限制就能实现&amp;quot;修改并返回新对象&amp;quot;的模式。&lt;/p&gt;&lt;h2&gt;新增 json_validate() 函数&lt;/h2&gt;&lt;p&gt;在 PHP 8.3 之前，验证一个字符串是否是合法 JSON，通常需要 &lt;code&gt;json_decode&lt;/code&gt; + 检查 &lt;code&gt;json_last_error()&lt;/code&gt;，不仅浪费内存，写法也繁琐。PHP 8.3 提供了专用函数：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

$validJson&amp;nbsp;=&amp;nbsp;&amp;#39;{&amp;quot;name&amp;quot;:&amp;nbsp;&amp;quot;PHP&amp;quot;,&amp;nbsp;&amp;quot;version&amp;quot;:&amp;nbsp;8.3}&amp;#39;;
$invalidJson&amp;nbsp;=&amp;nbsp;&amp;#39;{name:&amp;nbsp;PHP}&amp;#39;;

var_dump(json_validate($validJson));&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;bool(true)
var_dump(json_validate($invalidJson));&amp;nbsp;//&amp;nbsp;bool(false)

//&amp;nbsp;实际场景：API&amp;nbsp;入参校验
function&amp;nbsp;handleRequest(string&amp;nbsp;$body):&amp;nbsp;array&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(!json_validate($body))&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;\InvalidArgumentException(&amp;#39;请求体必须是合法的&amp;nbsp;JSON&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;json_decode($body,&amp;nbsp;true);
}&lt;/pre&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;相比 &lt;code&gt;json_decode&lt;/code&gt;，&lt;code&gt;json_validate&lt;/code&gt; 不会构建数据结构，&lt;strong&gt;内存占用更低、速度更快&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;支持 &lt;code&gt;$depth&lt;/code&gt; 参数限制嵌套深度，防止恶意深层嵌套攻击&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;支持 &lt;code&gt;$flags&lt;/code&gt; 参数，与 &lt;code&gt;json_decode&lt;/code&gt; 保持一致&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;动态类常量与枚举成员获取（Dynamic Class Constant Fetch）&lt;/h2&gt;&lt;p&gt;PHP 8.3 支持通过动态表达式访问类常量和枚举成员，告别了以往必须用 &lt;code&gt;constant()&lt;/code&gt; 函数的繁琐写法：&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Config&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;DB_HOST&amp;nbsp;=&amp;nbsp;&amp;#39;localhost&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;DB_PORT&amp;nbsp;=&amp;nbsp;3306;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;const&amp;nbsp;REDIS_HOST&amp;nbsp;=&amp;nbsp;&amp;#39;redis&amp;#39;;
}

//&amp;nbsp;旧写法
$key&amp;nbsp;=&amp;nbsp;&amp;#39;DB_HOST&amp;#39;;
$value&amp;nbsp;=&amp;nbsp;constant(&amp;quot;Config::$key&amp;quot;);&amp;nbsp;//&amp;nbsp;繁琐

//&amp;nbsp;PHP&amp;nbsp;8.3&amp;nbsp;新写法
$value&amp;nbsp;=&amp;nbsp;Config::{$key};&amp;nbsp;//&amp;nbsp;简洁优雅

//&amp;nbsp;枚举同样支持
enum&amp;nbsp;Status:&amp;nbsp;string&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Active&amp;nbsp;=&amp;nbsp;&amp;#39;active&amp;#39;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&amp;nbsp;Inactive&amp;nbsp;=&amp;nbsp;&amp;#39;inactive&amp;#39;;
}

$name&amp;nbsp;=&amp;nbsp;&amp;#39;Active&amp;#39;;
$case&amp;nbsp;=&amp;nbsp;Status::{$name};&amp;nbsp;//&amp;nbsp;等同于&amp;nbsp;Status::Active
echo&amp;nbsp;$case-&amp;gt;value;&amp;nbsp;//&amp;nbsp;&amp;quot;active&amp;quot;&lt;/pre&gt;&lt;p&gt;这一特性在配置读取、策略模式、命令分发等场景中极为实用，大幅减少了 &lt;code&gt;match&lt;/code&gt; 或 &lt;code&gt;switch&lt;/code&gt; 的样板代码。&lt;/p&gt;&lt;h2&gt;升级建议与兼容性注意事项&lt;/h2&gt;&lt;p&gt;PHP 8.3 整体向下兼容性良好，但在升级前仍需注意以下几点：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;废弃项清理&lt;/strong&gt;：运行 &lt;code&gt;composer require --dev phpstan/phpstan&lt;/code&gt; 静态分析，提前发现废弃用法&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;扩展兼容性&lt;/strong&gt;：确认项目依赖的 C 扩展（如 imagick、redis）已提供 PHP 8.3 编译版本&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Composer 依赖&lt;/strong&gt;：执行 &lt;code&gt;composer update --dry-run&lt;/code&gt; 检查依赖库的版本约束&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;测试覆盖&lt;/strong&gt;：升级前确保关键路径有单元测试覆盖，建议在 CI 中先跑 PHP 8.3 测试矩阵&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;#&amp;nbsp;检查当前&amp;nbsp;PHP&amp;nbsp;版本
php&amp;nbsp;-v

#&amp;nbsp;使用&amp;nbsp;phpcs&amp;nbsp;检查兼容性
composer&amp;nbsp;require&amp;nbsp;--dev&amp;nbsp;phpcompatibility/php-compatibility
./vendor/bin/phpcs&amp;nbsp;--standard=PHPCompatibility&amp;nbsp;--runtime-set&amp;nbsp;testVersion&amp;nbsp;8.3&amp;nbsp;src/&lt;/pre&gt;&lt;p&gt;PHP 8.3 已进入活跃支持阶段，安全支持将持续到 2026 年底。现在升级，既能享受新特性带来的开发效率提升，也能确保生产环境持续获得安全更新。&lt;/p&gt;</description><pubDate>Sun, 12 Jul 2026 08:09:10 +0800</pubDate></item><item><title>PHP 8.4 新特性全解析：属性钩子与非对称可见性实战指南</title><link>https://blog.resmic.cn/post/321.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260711080318178372819868647.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;PHP 8.4 重磅登场：为什么开发者都在关注这次更新？&lt;/h2&gt;&lt;p&gt;PHP 8.4 于 2024 年 11 月正式发布，是近年来改动最为深远的版本之一。其中最受社区关注的两大特性——&lt;strong&gt;属性钩子（Property Hooks）&lt;/strong&gt;和&lt;strong&gt;非对称可见性（Asymmetric Visibility）&lt;/strong&gt;——彻底改变了开发者定义和操控类属性的方式。&lt;/p&gt;&lt;p&gt;在此之前，PHP 开发者要实现&amp;quot;只读写限制&amp;quot;或&amp;quot;属性变更拦截&amp;quot;，往往需要编写大量模板代码：私有属性 + getter + setter。这不仅冗余，还降低了代码的可读性。PHP 8.4 用极简语法一步到位解决了这个问题。&lt;/p&gt;&lt;p&gt;本文将带你系统掌握这两大特性，并通过真实场景的代码示例，让你立刻具备在项目中应用的能力。&lt;/p&gt;&lt;h2&gt;属性钩子（Property Hooks）详解&lt;/h2&gt;&lt;p&gt;属性钩子允许在类属性上直接定义 &lt;code&gt;get&lt;/code&gt; 和 &lt;code&gt;set&lt;/code&gt; 逻辑，而无需单独定义方法。语法简洁优雅，参考自 Kotlin 和 C# 等现代语言。&lt;/p&gt;&lt;h3&gt;基本语法&lt;/h3&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;User&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;string&amp;nbsp;$name&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;=&amp;gt;&amp;nbsp;strtoupper($this-&amp;gt;name);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(string&amp;nbsp;$value)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(strlen($value)&amp;nbsp;&amp;lt;&amp;nbsp;2)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;\ValueError(&amp;#39;Name&amp;nbsp;must&amp;nbsp;be&amp;nbsp;at&amp;nbsp;least&amp;nbsp;2&amp;nbsp;characters.&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;name&amp;nbsp;=&amp;nbsp;$value;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

$user&amp;nbsp;=&amp;nbsp;new&amp;nbsp;User();
$user-&amp;gt;name&amp;nbsp;=&amp;nbsp;&amp;#39;alice&amp;#39;;
echo&amp;nbsp;$user-&amp;gt;name;&amp;nbsp;//&amp;nbsp;输出:&amp;nbsp;ALICE&lt;/pre&gt;&lt;p&gt;上面示例中，&lt;code&gt;get&lt;/code&gt; 钩子在读取时将名字转为大写，&lt;code&gt;set&lt;/code&gt; 钩子在写入时验证长度。整个逻辑内聚在属性声明中，清晰直观。&lt;/p&gt;&lt;h3&gt;只定义 get 钩子：虚拟属性&lt;/h3&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Circle&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;__construct(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;float&amp;nbsp;$radius
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;float&amp;nbsp;$area&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;=&amp;gt;&amp;nbsp;M_PI&amp;nbsp;*&amp;nbsp;$this-&amp;gt;radius&amp;nbsp;**&amp;nbsp;2;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

$c&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Circle(5.0);
echo&amp;nbsp;$c-&amp;gt;area;&amp;nbsp;//&amp;nbsp;78.539816...
//&amp;nbsp;$c-&amp;gt;area&amp;nbsp;=&amp;nbsp;100;&amp;nbsp;//&amp;nbsp;抛出&amp;nbsp;Error：该属性只有&amp;nbsp;get&amp;nbsp;钩子&lt;/pre&gt;&lt;p&gt;仅定义 &lt;code&gt;get&lt;/code&gt; 的属性称为&amp;quot;虚拟属性&amp;quot;（Virtual Property），它不占用实际存储空间，等同于一个计算属性。&lt;/p&gt;&lt;h2&gt;非对称可见性（Asymmetric Visibility）&lt;/h2&gt;&lt;p&gt;非对称可见性允许为属性的&amp;quot;读&amp;quot;和&amp;quot;写&amp;quot;分别指定不同的访问级别，语法为 &lt;code&gt;public private(set)&lt;/code&gt; 或 &lt;code&gt;public protected(set)&lt;/code&gt;。&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Order&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;private(set)&amp;nbsp;int&amp;nbsp;$status&amp;nbsp;=&amp;nbsp;0;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;confirm():&amp;nbsp;void&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;status&amp;nbsp;=&amp;nbsp;1;&amp;nbsp;//&amp;nbsp;类内部可写
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

$order&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Order();
echo&amp;nbsp;$order-&amp;gt;status;&amp;nbsp;//&amp;nbsp;0&amp;nbsp;——&amp;nbsp;外部可读
//&amp;nbsp;$order-&amp;gt;status&amp;nbsp;=&amp;nbsp;2;&amp;nbsp;//&amp;nbsp;致命错误：外部不可写
$order-&amp;gt;confirm();
echo&amp;nbsp;$order-&amp;gt;status;&amp;nbsp;//&amp;nbsp;1&lt;/pre&gt;&lt;p&gt;这与 PHP 8.1 的 &lt;code&gt;readonly&lt;/code&gt; 不同：&lt;code&gt;readonly&lt;/code&gt; 只能写一次，而非对称可见性允许在类内部多次修改，提供了更灵活的封装控制。&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;public private(set)&lt;/code&gt;：外部可读，仅类自身可写&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;public protected(set)&lt;/code&gt;：外部可读，类自身及子类可写&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;protected private(set)&lt;/code&gt;：子类可读，仅类自身可写&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;两者结合使用：构建健壮的值对象&lt;/h2&gt;&lt;p&gt;属性钩子和非对称可见性可以组合使用，构建真正健壮的值对象（Value Object）或领域模型。&lt;/p&gt;&lt;pre&gt;&amp;lt;?php

class&amp;nbsp;Temperature&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;private(set)&amp;nbsp;float&amp;nbsp;$celsius&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;set(float&amp;nbsp;$value)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;($value&amp;nbsp;&amp;lt;&amp;nbsp;-273.15)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&amp;nbsp;new&amp;nbsp;\RangeException(&amp;#39;Temperature&amp;nbsp;below&amp;nbsp;absolute&amp;nbsp;zero!&amp;#39;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;celsius&amp;nbsp;=&amp;nbsp;$value;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;float&amp;nbsp;$fahrenheit&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;=&amp;gt;&amp;nbsp;$this-&amp;gt;celsius&amp;nbsp;*&amp;nbsp;9&amp;nbsp;/&amp;nbsp;5&amp;nbsp;+&amp;nbsp;32;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&amp;nbsp;function&amp;nbsp;__construct(float&amp;nbsp;$celsius)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$this-&amp;gt;celsius&amp;nbsp;=&amp;nbsp;$celsius;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

$t&amp;nbsp;=&amp;nbsp;new&amp;nbsp;Temperature(100.0);
echo&amp;nbsp;$t-&amp;gt;celsius;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;100
echo&amp;nbsp;$t-&amp;gt;fahrenheit;&amp;nbsp;//&amp;nbsp;212
//&amp;nbsp;$t-&amp;gt;fahrenheit&amp;nbsp;=&amp;nbsp;300;&amp;nbsp;//&amp;nbsp;Error:&amp;nbsp;只读虚拟属性
//&amp;nbsp;$t-&amp;gt;celsius&amp;nbsp;=&amp;nbsp;500;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Error:&amp;nbsp;外部不可写&lt;/pre&gt;&lt;p&gt;这种方式无需任何手写 getter/setter，就实现了完整的数据封装、校验和派生计算，代码量减少约 60%，可读性大幅提升。&lt;/p&gt;&lt;h2&gt;迁移建议与兼容性注意事项&lt;/h2&gt;&lt;p&gt;在将已有项目升级到 PHP 8.4 并使用新特性时，有以下几点需要特别注意：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;接口中不可使用钩子&lt;/strong&gt;：接口中的属性声明不支持 &lt;code&gt;get&lt;/code&gt;/&lt;code&gt;set&lt;/code&gt; 钩子，只能在具体类中定义。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;序列化行为&lt;/strong&gt;：带钩子的属性在 &lt;code&gt;serialize()&lt;/code&gt; 和 &lt;code&gt;json_encode()&lt;/code&gt; 时，使用的是 &lt;code&gt;get&lt;/code&gt; 钩子的返回值，需留意副作用。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;与 readonly 不可混用&lt;/strong&gt;：&lt;code&gt;readonly&lt;/code&gt; 属性不能同时定义 &lt;code&gt;set&lt;/code&gt; 钩子；虚拟属性（仅 get）与 readonly 有类似效果但机制不同。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;PHP 8.4 最低版本要求&lt;/strong&gt;：确保服务器 PHP 版本 &amp;gt;= 8.4，可通过 &lt;code&gt;php -v&lt;/code&gt; 验证。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;静态分析工具更新&lt;/strong&gt;：PHPStan、Psalm 等工具需升级到支持 PHP 8.4 语法的最新版本。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;#&amp;nbsp;检查&amp;nbsp;PHP&amp;nbsp;版本
php&amp;nbsp;-v

#&amp;nbsp;使用&amp;nbsp;Composer&amp;nbsp;约束最低版本
#&amp;nbsp;composer.json
#&amp;nbsp;&amp;quot;require&amp;quot;:&amp;nbsp;{&amp;nbsp;&amp;quot;php&amp;quot;:&amp;nbsp;&amp;quot;&amp;gt;=8.4&amp;quot;&amp;nbsp;}&lt;/pre&gt;&lt;p&gt;总体而言，PHP 8.4 的这两大特性是对面向对象编程范式的重大强化，建议新项目直接采用，老项目可在迭代重构时逐步引入。属性钩子和非对称可见性让 PHP 在现代语言特性上又迈出了坚实一步，值得每位 PHP 开发者深入了解和实践。&lt;/p&gt;</description><pubDate>Sat, 11 Jul 2026 08:07:20 +0800</pubDate></item><item><title>PHP 8.3 新特性全解析：类型系统、只读类与性能优化实战</title><link>https://blog.resmic.cn/post/320.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260710080438178364187811567.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;&gt;&lt;/p&gt;

&lt;h2&gt;PHP 8.3 概览：为什么值得升级&lt;/h2&gt;
&lt;p&gt;PHP 8.3 于 2023 年 11 月正式发布，是 PHP 8.x 系列迄今最完善的版本。相较于 8.2，它在类型系统、只读属性、内置函数以及错误处理等方面均有显著改进。无论你是维护遗留项目还是构建全新应用，理解这些变化都有助于写出更健壮、更高效的代码。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;更严格的类型约束，减少运行时隐性错误&lt;/li&gt;
  &lt;li&gt;只读类（Readonly Classes）全面增强&lt;/li&gt;
  &lt;li&gt;新增多个实用内置函数，减少重复造轮子&lt;/li&gt;
  &lt;li&gt;JSON 验证函数，一行代码搞定格式校验&lt;/li&gt;
  &lt;li&gt;动态类常量获取，写出更灵活的元编程代码&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;只读类与只读属性的升级&lt;/h2&gt;
&lt;p&gt;PHP 8.2 引入了 &lt;code&gt;readonly class&lt;/code&gt;，但存在一些限制。8.3 进一步完善了这一特性，允许在子类中覆盖只读属性的初始化，同时支持在 &lt;code&gt;clone&lt;/code&gt; 表达式中修改只读属性，极大提升了不可变对象的实用性。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

// PHP 8.3：clone 时可修改 readonly 属性
readonly class UserProfile {
    public function __construct(
        public string $name,
        public string $email,
        public int    $age,
    ) {}
}

$user = new UserProfile('Alice', 'alice@example.com', 28);

// 使用 clone with 语法（PHP 8.4 正式，8.3 通过 clone + 覆盖模拟）
$updated = clone $user;
// 在 8.3 中可通过构造函数重建来实现类似效果
$updated = new UserProfile($user-&gt;name, 'newemail@example.com', $user-&gt;age);

echo $updated-&gt;email; // newemail@example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于需要大量值对象（Value Object）的 DDD 项目，这一改进能让代码更简洁，同时保持对象不可变性的语义保证。&lt;/p&gt;

&lt;h2&gt;动态类常量与枚举成员访问&lt;/h2&gt;
&lt;p&gt;在 PHP 8.3 之前，访问类常量必须使用硬编码字符串或复杂的反射机制。现在，你可以通过变量动态获取类常量，这对于根据配置或用户输入选择枚举值非常有用。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

enum Status: string {
    case Active   = 'active';
    case Inactive = 'inactive';
    case Pending  = 'pending';
}

// PHP 8.3：动态常量/枚举获取
$statusKey = 'Active';
$status = Status::{$statusKey};  // 等价于 Status::Active
echo $status-&gt;value; // active

// 同样适用于普通类常量
class Config {
    const DB_HOST = 'localhost';
    const DB_PORT = 3306;
}

$key = 'DB_HOST';
echo Config::{$key}; // localhost
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个特性在实现策略模式、工厂方法或动态路由映射时特别实用，无需再借助 &lt;code&gt;constant()&lt;/code&gt; 函数或反射类。&lt;/p&gt;

&lt;h2&gt;新增内置函数：json_validate、mb_str_pad 等&lt;/h2&gt;
&lt;p&gt;PHP 8.3 新增了几个呼声极高的内置函数，覆盖 JSON 验证、字符串填充等常见场景。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

// 1. json_validate()：只验证不解析，性能更好
$rawInput = '{&quot;name&quot;:&quot;Bob&quot;,&quot;age&quot;:30}';
if (json_validate($rawInput)) {
    $data = json_decode($rawInput, true);
    echo &quot;Valid JSON, name: &quot; . $data['name'];
} else {
    echo &quot;Invalid JSON&quot;;
}

// 2. mb_str_pad()：多字节安全的字符串填充
$title = '标题';
echo mb_str_pad($title, 10, '─', STR_PAD_BOTH); 
// ────标题────

// 3. 数组解包增强：str_contains / array_is_list 更稳定
$list = [1, 2, 3];
var_dump(array_is_list($list)); // true

$assoc = ['a' =&gt; 1, 'b' =&gt; 2];
var_dump(array_is_list($assoc)); // false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;json_validate()&lt;/code&gt; 是最受欢迎的新增函数之一。在只需验证格式而无需解析内容的场景（如 webhook 接收、API 网关校验），它的性能比 &lt;code&gt;json_decode()&lt;/code&gt; 后检查返回值高出约 30%。&lt;/p&gt;

&lt;h2&gt;类型系统增强：交叉类型与 never 返回类型&lt;/h2&gt;
&lt;p&gt;PHP 8.3 对类型系统做了进一步完善，交叉类型（Intersection Types）更加稳定，&lt;code&gt;never&lt;/code&gt; 返回类型也在更多场景下得到支持。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

interface Serializable {
    public function serialize(): string;
}

interface Loggable {
    public function log(): void;
}

// 交叉类型：参数必须同时实现两个接口
function processEntity(Serializable&amp;amp;Loggable $entity): void {
    $entity-&gt;log();
    $data = $entity-&gt;serialize();
    // ...
}

// never 类型：函数永不正常返回（抛异常或终止）
function throwNotFound(string $resource): never {
    throw new \RuntimeException(&quot;Resource not found: {$resource}&quot;);
}

// 结合 match 表达式使用
function getStatusLabel(int $code): string {
    return match(true) {
        $code &gt;= 200 &amp;amp;&amp;amp; $code &lt; 300 =&gt; 'Success',
        $code &gt;= 400 &amp;amp;&amp;amp; $code &lt; 500 =&gt; 'Client Error',
        $code &gt;= 500                  =&gt; 'Server Error',
        default                       =&gt; throwNotFound(&quot;status:{$code}&quot;),
    };
}

echo getStatusLabel(200); // Success
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;错误处理改进：更精确的 TypeError 信息&lt;/h2&gt;
&lt;p&gt;PHP 8.3 改进了类型错误的错误消息，使调试更加高效。当传入错误类型的参数时，错误信息现在会精确指出期望类型、实际传入类型以及出错位置。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php

function calculateArea(float $width, float $height): float {
    return $width * $height;
}

// 传入字符串触发 TypeError
try {
    calculateArea('10px', 20);
} catch (\TypeError $e) {
    // PHP 8.3 错误信息示例：
    // calculateArea(): Argument #1 ($width) must be of type float, 
    // string given, called in /app/test.php on line 8
    echo $e-&gt;getMessage();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于大型项目，更清晰的错误信息意味着更短的调试时间。配合 Xdebug 或 Sentry，可以快速定位生产环境中的类型错误。&lt;/p&gt;

&lt;h2&gt;性能提升与 JIT 优化&lt;/h2&gt;
&lt;p&gt;PHP 8.3 在 JIT（即时编译）方面做了多项优化，针对数值计算密集型场景性能提升尤为明显。官方基准测试显示，在 Symfony 和 Laravel 典型工作负载下，8.3 比 8.2 快约 5-8%。&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;OPcache 改进&lt;/strong&gt;：减少了字节码缓存的内存占用&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;字符串操作优化&lt;/strong&gt;：常用字符串函数（&lt;code&gt;str_replace&lt;/code&gt;、&lt;code&gt;implode&lt;/code&gt;）底层实现重写&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fiber 稳定性&lt;/strong&gt;：协程支持更加稳健，适合构建异步应用&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;GC 优化&lt;/strong&gt;：垃圾回收算法调整，长生命周期进程内存更稳定&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;&amp;lt;?php
// 利用 Fiber 实现轻量级并发
$fiber = new Fiber(function(): void {
    $value = Fiber::suspend('first');
    echo &quot;Got: {$value}\n&quot;;
    Fiber::suspend('second');
});

$first  = $fiber-&gt;start();          // first
$second = $fiber-&gt;resume('hello');  // Got: hello, second
echo $first . &quot;\n&quot;;   // first
echo $second . &quot;\n&quot;;  // second
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;升级实践：如何平滑迁移到 PHP 8.3&lt;/h2&gt;
&lt;p&gt;升级前建议遵循以下步骤，降低风险：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;运行 php-compatibility-checker&lt;/strong&gt;：扫描代码库中的不兼容用法&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;检查废弃特性&lt;/strong&gt;：重点关注 &lt;code&gt;utf8_encode()&lt;/code&gt;/&lt;code&gt;utf8_decode()&lt;/code&gt; 已移除，改用 &lt;code&gt;mb_convert_encoding()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;更新 Composer 依赖&lt;/strong&gt;：确保所有包支持 PHP 8.3，&lt;code&gt;composer update --with-all-dependencies&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;在 CI 中添加 8.3 矩阵&lt;/strong&gt;：GitHub Actions / GitLab CI 增加 PHP 8.3 测试环节&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;灰度发布&lt;/strong&gt;：先在非核心服务升级，观察一周后再全量切换&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 使用 phpcs 检查不兼容代码
composer require --dev phpcompatibility/php-compatibility
./vendor/bin/phpcs --standard=PHPCompatibility \
  --runtime-set testVersion 8.3 \
  src/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PHP 8.3 向下兼容性良好，大多数遵循 PSR 标准的项目可以无缝升级。最大的风险点是直接使用了已废弃内部函数或依赖旧版扩展的项目，提前用工具扫描可以避免生产事故。&lt;/p&gt;
</description><pubDate>Fri, 10 Jul 2026 08:05:24 +0800</pubDate></item><item><title>Jetpack Compose 性能优化实战：5 个方向让你的 App 流畅如丝</title><link>https://blog.resmic.cn/post/319.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260709080324178355540440268.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;/&gt;&lt;/p&gt;&lt;h2&gt;前言：Compose 已成 Android 开发主流&lt;/h2&gt;&lt;p&gt;Jetpack Compose 自 2021 年正式发布以来，已经成为 Android 现代 UI 开发的标准方案。越来越多的团队将存量代码迁移至 Compose，或直接用 Compose 从零构建新应用。然而，随着 Compose UI 复杂度不断提升，&lt;strong&gt;性能问题&lt;/strong&gt;也开始浮出水面：列表滑动卡顿、动画掉帧、冷启动耗时……&lt;/p&gt;&lt;p&gt;本文从实战角度出发，梳理 Compose 性能优化最常见的 5 个方向，每个方向附带可直接复用的代码片段，帮助你快速定位并解决性能瓶颈。&lt;/p&gt;&lt;h2&gt;一、理解重组（Recomposition）：从根源防止无效渲染&lt;/h2&gt;&lt;p&gt;Compose 的核心机制是&lt;strong&gt;响应式重组&lt;/strong&gt;——状态变化时，框架自动重新执行相关 Composable。但如果重组范围控制不当，就会导致大量不必要的 UI 重建，造成明显卡顿。&lt;/p&gt;&lt;p&gt;常见错误：在父级 Composable 里创建 lambda 或 List，每次重组都产生新对象，导致子组件被强制重组。&lt;/p&gt;&lt;pre&gt;//&amp;nbsp;❌&amp;nbsp;错误写法：每次父组件重组都会创建新&amp;nbsp;List
@Composable
fun&amp;nbsp;ParentScreen(viewModel:&amp;nbsp;MyViewModel)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;items&amp;nbsp;=&amp;nbsp;listOf(&amp;quot;A&amp;quot;,&amp;nbsp;&amp;quot;B&amp;quot;,&amp;nbsp;&amp;quot;C&amp;quot;)&amp;nbsp;&amp;nbsp;//&amp;nbsp;每次重组都是新对象
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemList(items&amp;nbsp;=&amp;nbsp;items)
}

//&amp;nbsp;✅&amp;nbsp;正确写法：从&amp;nbsp;ViewModel&amp;nbsp;稳定来源获取
@Composable
fun&amp;nbsp;ParentScreen(viewModel:&amp;nbsp;MyViewModel)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;items&amp;nbsp;by&amp;nbsp;viewModel.items.collectAsStateWithLifecycle()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ItemList(items&amp;nbsp;=&amp;nbsp;items)
}&lt;/pre&gt;&lt;p&gt;使用 &lt;code&gt;@Stable&lt;/code&gt; 和 &lt;code&gt;@Immutable&lt;/code&gt; 注解帮助 Compose 编译器识别稳定类型，跳过不必要的重组：&lt;/p&gt;&lt;pre&gt;@Immutable
data&amp;nbsp;class&amp;nbsp;UserProfile(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;id:&amp;nbsp;Long,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;name:&amp;nbsp;String,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;avatarUrl:&amp;nbsp;String
)&lt;/pre&gt;&lt;h2&gt;二、LazyList 优化：让列表滑动丝滑如油&lt;/h2&gt;&lt;p&gt;LazyColumn / LazyRow 是 Compose 中最常用的列表组件，也是性能问题的重灾区。以下几点是高频踩坑点：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;key 参数必须指定&lt;/strong&gt;：为每个 item 提供稳定唯一的 key，避免全量重组。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;避免在 item lambda 内做耗时计算&lt;/strong&gt;：使用 &lt;code&gt;remember&lt;/code&gt; 缓存派生数据。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;图片加载使用异步库&lt;/strong&gt;：Coil / Glide for Compose，避免主线程解码图片。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;itemsIndexed 谨慎使用&lt;/strong&gt;：如果只需 item 不需要 index，用 items 即可。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;LazyColumn&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;items&amp;nbsp;=&amp;nbsp;articleList,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;key&amp;nbsp;=&amp;nbsp;{&amp;nbsp;article&amp;nbsp;-&amp;gt;&amp;nbsp;article.id&amp;nbsp;}&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;提供稳定&amp;nbsp;key
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;article&amp;nbsp;-&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;formattedDate&amp;nbsp;=&amp;nbsp;remember(article.id)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;缓存耗时格式化操作
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SimpleDateFormat(&amp;quot;yyyy-MM-dd&amp;quot;,&amp;nbsp;Locale.getDefault())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.format(Date(article.timestamp))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ArticleCard(article&amp;nbsp;=&amp;nbsp;article,&amp;nbsp;date&amp;nbsp;=&amp;nbsp;formattedDate)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;对于超长列表（&amp;gt;1000 项），建议结合 Paging 3 使用 &lt;code&gt;collectAsLazyPagingItems()&lt;/code&gt;，实现分页加载，进一步降低内存压力。&lt;/p&gt;&lt;h2&gt;三、使用 derivedStateOf 避免过度重组&lt;/h2&gt;&lt;p&gt;当某个状态需要基于其他状态派生计算，且计算成本较高时，应使用 &lt;code&gt;derivedStateOf&lt;/code&gt; 包裹，确保只有在派生结果真正变化时才触发重组。&lt;/p&gt;&lt;pre&gt;@Composable
fun&amp;nbsp;ScrollToTopButton(listState:&amp;nbsp;LazyListState)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;❌&amp;nbsp;错误：每次&amp;nbsp;firstVisibleItemIndex&amp;nbsp;变化都重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;showButton&amp;nbsp;=&amp;nbsp;listState.firstVisibleItemIndex&amp;nbsp;&amp;gt;&amp;nbsp;0

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;✅&amp;nbsp;正确：只有布尔值从&amp;nbsp;false→true&amp;nbsp;或&amp;nbsp;true→false&amp;nbsp;时才重组
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;val&amp;nbsp;showButton&amp;nbsp;by&amp;nbsp;remember&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;derivedStateOf&amp;nbsp;{&amp;nbsp;listState.firstVisibleItemIndex&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AnimatedVisibility(visible&amp;nbsp;=&amp;nbsp;showButton)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FloatingActionButton(onClick&amp;nbsp;=&amp;nbsp;{&amp;nbsp;/*&amp;nbsp;scroll&amp;nbsp;to&amp;nbsp;top&amp;nbsp;*/&amp;nbsp;})&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Icon(Icons.Default.KeyboardArrowUp,&amp;nbsp;&amp;quot;回到顶部&amp;quot;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}&lt;/pre&gt;&lt;p&gt;这个优化在列表滚动场景尤其明显，可以将按钮区域的重组次数从&amp;quot;每帧&amp;quot;降低到&amp;quot;仅切换阈值时&amp;quot;。&lt;/p&gt;&lt;h2&gt;四、借助 Android Studio 工具定量分析&lt;/h2&gt;&lt;p&gt;性能优化不能只凭感觉，Android Studio 提供了强大的 Compose 专属工具链：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Layout Inspector&lt;/strong&gt;：实时查看 Compose 树结构，标注哪些组件正在重组（绿色高亮闪烁）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Composition Tracing&lt;/strong&gt;：在 Systrace / Perfetto 中记录 Composable 函数调用，精确定位热点。需在 &lt;code&gt;build.gradle&lt;/code&gt; 中启用：&lt;code&gt;composeOptions { kotlinCompilerExtensionVersion = &amp;quot;1.5.x&amp;quot; }&lt;/code&gt;。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recomposition Counts&lt;/strong&gt;：Layout Inspector 的 Recomposition 面板可直观看到每个节点的重组次数和跳过次数。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;//&amp;nbsp;build.gradle&amp;nbsp;(app)
android&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;buildFeatures&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;compose&amp;nbsp;=&amp;nbsp;true
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;composeOptions&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kotlinCompilerExtensionVersion&amp;nbsp;=&amp;nbsp;&amp;quot;1.5.14&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}

dependencies&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;启用&amp;nbsp;Composition&amp;nbsp;Tracing
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;implementation&amp;nbsp;&amp;quot;androidx.compose.runtime:runtime-tracing:1.0.0-beta01&amp;quot;
}&lt;/pre&gt;&lt;p&gt;建议在优化前后各跑一次 Systrace，用数据说话，而不是凭肉眼感知&amp;quot;好像快了一点&amp;quot;。&lt;/p&gt;&lt;h2&gt;五、实战建议与常见误区总结&lt;/h2&gt;&lt;p&gt;经过大量项目实践，以下几点是最值得反复强调的：&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;不要过早优化&lt;/strong&gt;：先用 Layout Inspector 确认存在重组问题，再针对性优化，避免增加不必要的代码复杂度。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;ViewModel + StateFlow 是标准搭档&lt;/strong&gt;：状态统一从 ViewModel 的 StateFlow 流入 UI，配合 &lt;code&gt;collectAsStateWithLifecycle()&lt;/code&gt; 自动感知生命周期，既安全又高效。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;remember 不是万能的&lt;/strong&gt;：过度使用 remember 会增加内存占用，只对真正昂贵的计算使用。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modifier 顺序影响性能&lt;/strong&gt;：&lt;code&gt;Modifier.clip().background()&lt;/code&gt; 与 &lt;code&gt;Modifier.background().clip()&lt;/code&gt; 产生不同的绘制层级，前者开销更小。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;避免在 Composable 顶层创建协程 scope&lt;/strong&gt;：使用 &lt;code&gt;rememberCoroutineScope()&lt;/code&gt; 绑定生命周期，防止内存泄漏。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Jetpack Compose 的性能优化是一个系统工程，没有银弹。理解重组机制是基础，善用官方工具是手段，最终目标是让用户感受到流畅自然的交互体验。随着 Compose 编译器的持续演进（Strong Skipping Mode 等新特性），未来的优化空间还会进一步扩大。&lt;/p&gt;</description><pubDate>Thu, 09 Jul 2026 08:03:44 +0800</pubDate></item><item><title>Claude 4.5 实战指南：工具调用、视觉理解与 AI Agent 构建</title><link>https://blog.resmic.cn/post/318.html</link><description>&lt;p&gt;&lt;img src=&quot;https://blog.resmic.cn/zb_users/upload/2026/07/20260708080954178346939465788.jpg&quot; alt=&quot;封面&quot; style=&quot;width:100%;&quot;&gt;&lt;/p&gt;

&lt;h2&gt;Claude 4.5 的能力全景：不只是聊天机器人&lt;/h2&gt;
&lt;p&gt;2025年以来，大语言模型的竞争进入白热化阶段。Anthropic 发布的 Claude 4.5 在多项基准测试中刷新了纪录，但更重要的是，它在实际工程场景中展现出了前所未有的实用性。与上一代相比，Claude 4.5 带来了三大核心升级：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;200K 上下文窗口&lt;/strong&gt;：可一次性处理长达 150 万字的文档，适合代码库分析、长文档理解等场景&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;增强型工具调用&lt;/strong&gt;：支持并行工具调用（Parallel Tool Use），AI Agent 可同时触发多个 API&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;原生视觉理解&lt;/strong&gt;：直接分析图片、图表、截图，无需额外的视觉模型&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;计算机使用（Computer Use）稳定版&lt;/strong&gt;：可操控浏览器和桌面完成复杂任务&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些特性组合在一起，让 Claude 4.5 成为构建生产级 AI Agent 的理想基座。下面我们通过实战代码来逐步解锁这些能力。&lt;/p&gt;

&lt;h2&gt;环境搭建与基础配置&lt;/h2&gt;
&lt;p&gt;首先安装最新版 Anthropic SDK，确保支持 Claude 4.5 的全部特性：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 安装 SDK
pip install anthropic&gt;=0.30.0

# 验证安装
python3 -c &quot;import anthropic; print(anthropic.__version__)&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;基础客户端初始化：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import anthropic
import os

client = anthropic.Anthropic(
    api_key=os.environ.get(&quot;ANTHROPIC_API_KEY&quot;)
)

# 测试基本对话
response = client.messages.create(
    model=&quot;claude-sonnet-4-5&quot;,
    max_tokens=1024,
    messages=[
        {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;请简述你的核心能力&quot;}
    ]
)
print(response.content[0].text)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;对于国内开发者，如果无法直接访问 Anthropic API，可以通过腾讯云、阿里云等云厂商提供的代理端点，或者使用 AWS Bedrock、Google Vertex AI 上的 Claude 模型。&lt;/p&gt;

&lt;h2&gt;构建支持工具调用的 AI Agent&lt;/h2&gt;
&lt;p&gt;Claude 4.5 最强大的特性之一是工具调用（Tool Use）。我们来构建一个能够查询天气、搜索新闻的智能助手：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import anthropic
import json
import requests

client = anthropic.Anthropic()

# 定义工具
tools = [
    {
        &quot;name&quot;: &quot;get_weather&quot;,
        &quot;description&quot;: &quot;获取指定城市的实时天气信息&quot;,
        &quot;input_schema&quot;: {
            &quot;type&quot;: &quot;object&quot;,
            &quot;properties&quot;: {
                &quot;city&quot;: {
                    &quot;type&quot;: &quot;string&quot;,
                    &quot;description&quot;: &quot;城市名称，如：北京、上海&quot;
                }
            },
            &quot;required&quot;: [&quot;city&quot;]
        }
    },
    {
        &quot;name&quot;: &quot;search_news&quot;,
        &quot;description&quot;: &quot;搜索最新技术新闻&quot;,
        &quot;input_schema&quot;: {
            &quot;type&quot;: &quot;object&quot;,
            &quot;properties&quot;: {
                &quot;query&quot;: {
                    &quot;type&quot;: &quot;string&quot;,
                    &quot;description&quot;: &quot;搜索关键词&quot;
                },
                &quot;limit&quot;: {
                    &quot;type&quot;: &quot;integer&quot;,
                    &quot;description&quot;: &quot;返回结果数量，默认5&quot;,
                    &quot;default&quot;: 5
                }
            },
            &quot;required&quot;: [&quot;query&quot;]
        }
    }
]

# 工具执行函数
def execute_tool(tool_name: str, tool_input: dict) -&gt; str:
    if tool_name == &quot;get_weather&quot;:
        # 实际项目中调用真实天气 API
        city = tool_input[&quot;city&quot;]
        return json.dumps({
            &quot;city&quot;: city,
            &quot;temperature&quot;: &quot;28°C&quot;,
            &quot;condition&quot;: &quot;晴天&quot;,
            &quot;humidity&quot;: &quot;65%&quot;
        }, ensure_ascii=False)
    
    elif tool_name == &quot;search_news&quot;:
        query = tool_input[&quot;query&quot;]
        limit = tool_input.get(&quot;limit&quot;, 5)
        # 模拟搜索结果
        return json.dumps({
            &quot;results&quot;: [
                {&quot;title&quot;: f&quot;关于{query}的最新进展&quot;, &quot;url&quot;: &quot;https://example.com/1&quot;},
                {&quot;title&quot;: f&quot;{query}技术深度解析&quot;, &quot;url&quot;: &quot;https://example.com/2&quot;}
            ][:limit]
        }, ensure_ascii=False)
    
    return &quot;工具执行失败&quot;

# Agent 主循环
def run_agent(user_message: str):
    messages = [{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: user_message}]
    
    while True:
        response = client.messages.create(
            model=&quot;claude-sonnet-4-5&quot;,
            max_tokens=4096,
            tools=tools,
            messages=messages
        )
        
        # 如果没有工具调用，返回最终结果
        if response.stop_reason == &quot;end_turn&quot;:
            return response.content[0].text
        
        # 处理工具调用
        tool_results = []
        for block in response.content:
            if block.type == &quot;tool_use&quot;:
                result = execute_tool(block.name, block.input)
                tool_results.append({
                    &quot;type&quot;: &quot;tool_result&quot;,
                    &quot;tool_use_id&quot;: block.id,
                    &quot;content&quot;: result
                })
        
        # 将工具结果加入对话历史
        messages.append({&quot;role&quot;: &quot;assistant&quot;, &quot;content&quot;: response.content})
        messages.append({&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: tool_results})

# 测试
result = run_agent(&quot;帮我查一下北京今天的天气，同时搜索一下最新的 AI 技术新闻&quot;)
print(result)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;上面的代码实现了一个基础的 ReAct（Reasoning + Acting）循环。Claude 会自动判断何时需要调用工具，调用后将结果整合进推理过程，最终给出综合回答。&lt;/p&gt;

&lt;h2&gt;视觉理解：让 AI 读懂图表和截图&lt;/h2&gt;
&lt;p&gt;Claude 4.5 的视觉能力在工程场景中极为实用。以下是常见的三种用法：&lt;/p&gt;

&lt;h3&gt;1. 分析上传的图片文件&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import base64

def analyze_image(image_path: str, question: str) -&gt; str:
    with open(image_path, &quot;rb&quot;) as f:
        image_data = base64.standard_b64encode(f.read()).decode(&quot;utf-8&quot;)
    
    # 自动检测图片格式
    ext = image_path.split(&quot;.&quot;)[-1].lower()
    media_type_map = {
        &quot;jpg&quot;: &quot;image/jpeg&quot;, &quot;jpeg&quot;: &quot;image/jpeg&quot;,
        &quot;png&quot;: &quot;image/png&quot;, &quot;gif&quot;: &quot;image/gif&quot;,
        &quot;webp&quot;: &quot;image/webp&quot;
    }
    media_type = media_type_map.get(ext, &quot;image/jpeg&quot;)
    
    response = client.messages.create(
        model=&quot;claude-sonnet-4-5&quot;,
        max_tokens=2048,
        messages=[
            {
                &quot;role&quot;: &quot;user&quot;,
                &quot;content&quot;: [
                    {
                        &quot;type&quot;: &quot;image&quot;,
                        &quot;source&quot;: {
                            &quot;type&quot;: &quot;base64&quot;,
                            &quot;media_type&quot;: media_type,
                            &quot;data&quot;: image_data
                        }
                    },
                    {
                        &quot;type&quot;: &quot;text&quot;,
                        &quot;text&quot;: question
                    }
                ]
            }
        ]
    )
    return response.content[0].text

# 使用示例
result = analyze_image(&quot;chart.png&quot;, &quot;请分析这张图表中的数据趋势，指出关键拐点&quot;)
print(result)&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;2. 直接通过 URL 分析网络图片&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;response = client.messages.create(
    model=&quot;claude-sonnet-4-5&quot;,
    max_tokens=1024,
    messages=[
        {
            &quot;role&quot;: &quot;user&quot;,
            &quot;content&quot;: [
                {
                    &quot;type&quot;: &quot;image&quot;,
                    &quot;source&quot;: {
                        &quot;type&quot;: &quot;url&quot;,
                        &quot;url&quot;: &quot;https://example.com/architecture-diagram.png&quot;
                    }
                },
                {
                    &quot;type&quot;: &quot;text&quot;,
                    &quot;text&quot;: &quot;请描述这张系统架构图，并指出潜在的单点故障&quot;
                }
            ]
        }
    ]
)
print(response.content[0].text)&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;生产实践：流式输出与错误处理&lt;/h2&gt;
&lt;p&gt;在生产环境中，流式输出（Streaming）和健壮的错误处理是必不可少的。以下是一个完整的生产级封装示例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from anthropic import APIError, APITimeoutError, RateLimitError
import time
from typing import Generator

def stream_response(
    messages: list,
    system: str = &quot;&quot;,
    max_retries: int = 3
) -&gt; Generator[str, None, None]:
    &quot;&quot;&quot;流式输出，带自动重试逻辑&quot;&quot;&quot;
    
    for attempt in range(max_retries):
        try:
            with client.messages.stream(
                model=&quot;claude-sonnet-4-5&quot;,
                max_tokens=8192,
                system=system,
                messages=messages
            ) as stream:
                for text in stream.text_stream:
                    yield text
            return  # 成功，退出重试循环
            
        except RateLimitError as e:
            if attempt &lt; max_retries - 1:
                wait_time = 2 ** attempt  # 指数退避
                print(f&quot;触发限流，{wait_time}秒后重试...&quot;)
                time.sleep(wait_time)
            else:
                raise
                
        except APITimeoutError:
            if attempt &lt; max_retries - 1:
                print(f&quot;请求超时，正在重试（{attempt+1}/{max_retries}）...&quot;)
                time.sleep(1)
            else:
                raise
                
        except APIError as e:
            print(f&quot;API 错误: {e.status_code} - {e.message}&quot;)
            raise

# 使用示例
for chunk in stream_response(
    messages=[{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;请写一篇关于 Transformer 架构的技术博客&quot;}],
    system=&quot;你是一名专业的技术博客作者&quot;
):
    print(chunk, end=&quot;&quot;, flush=True)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;对于需要处理超长文档的场景（如代码库分析），可以利用 Claude 4.5 的 200K 上下文，一次性传入整个代码仓库进行分析，而无需复杂的分块和检索逻辑。&lt;/p&gt;

&lt;h2&gt;总结与最佳实践&lt;/h2&gt;
&lt;p&gt;Claude 4.5 为 AI 应用开发提供了强大的基础能力。在实际项目中，建议遵循以下最佳实践：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;合理设置 max_tokens&lt;/strong&gt;：根据任务复杂度调整，避免不必要的 token 消耗&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;使用 system prompt 定义角色&lt;/strong&gt;：清晰的系统提示能显著提升输出质量&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;工具定义要精确&lt;/strong&gt;：详细的参数描述帮助模型正确理解何时及如何调用工具&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;实现指数退避重试&lt;/strong&gt;：生产环境必须处理 API 限流和超时情况&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;缓存常用提示&lt;/strong&gt;：利用 Prompt Caching 特性减少重复 token 消耗&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;监控 token 使用量&lt;/strong&gt;：通过 response.usage 跟踪成本，设置预算告警&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;随着 AI 能力的持续进化，掌握像 Claude 4.5 这样的前沿模型的工程用法，将成为开发者的核心竞争力。希望本文的代码示例能帮助你快速上手，在实际项目中落地 AI 应用。&lt;/p&gt;
</description><pubDate>Wed, 08 Jul 2026 08:10:16 +0800</pubDate></item></channel></rss>