Function Reference >> Other Basic Extensions >> SPL >> Datastructures

本文详细介绍了PHP SPL库中的SplQueue类,包括其构造方法、入队列enqueue、出队列dequeue及设置迭代模式setIteratorMode等核心功能。通过两个实例展示了不同迭代模式下队列的操作效果。
<?php
// +----------------------------------------------------------------------
// | Function Reference >> Other Basic Extensions >> SPL >> Datastructures
// +----------------------------------------------------------------------
// | SPL >> 数据结构 >> spl队列
// +----------------------------------------------------------------------
// | Author: alexander <gt199899@gmail.com>
// +----------------------------------------------------------------------
// | Datetime: 2017-09-21 16:26
// +----------------------------------------------------------------------
// | Perfect Is Shit
// +----------------------------------------------------------------------

/**
 * SplQueue extends SplDoublyLinkedList implements Iterator , ArrayAccess , Countable {
 *  --Methods--
 *      __construct ( void )
 *      mixed dequeue ( void )
 *      void enqueue ( mixed $value )
 *      void setIteratorMode ( int $mode )
 *  --Inherited methods--
 *      public void SplDoublyLinkedList::add ( mixed $index , mixed $newval )
 *      public mixed SplDoublyLinkedList::bottom ( void )
 *      public int SplDoublyLinkedList::count ( void )
 *      public mixed SplDoublyLinkedList::current ( void )
 *      public int SplDoublyLinkedList::getIteratorMode ( void )
 *      public bool SplDoublyLinkedList::isEmpty ( void )
 *      public mixed SplDoublyLinkedList::key ( void )
 *      public void SplDoublyLinkedList::next ( void )
 *      public bool SplDoublyLinkedList::offsetExists ( mixed $index )
 *      public mixed SplDoublyLinkedList::offsetGet ( mixed $index )
 *      public void SplDoublyLinkedList::offsetSet ( mixed $index , mixed $newval )
 *      public void SplDoublyLinkedList::offsetUnset ( mixed $index )
 *      public mixed SplDoublyLinkedList::pop ( void )
 *      public void SplDoublyLinkedList::prev ( void )
 *      public void SplDoublyLinkedList::push ( mixed $value )
 *      public void SplDoublyLinkedList::rewind ( void )
 *      public string SplDoublyLinkedList::serialize ( void )
 *      public void SplDoublyLinkedList::setIteratorMode ( int $mode )
 *      public mixed SplDoublyLinkedList::shift ( void )
 *      public mixed SplDoublyLinkedList::top ( void )
 *      public void SplDoublyLinkedList::unserialize ( string $serialized )
 *      public void SplDoublyLinkedList::unshift ( mixed $value )
 *      public bool SplDoublyLinkedList::valid ( void )
 *  }
 * SplQueue 拥有三个方法,继承自双向链表
 *  dequeue 出队列
 *  enqueue 入队列
 *  setIteratorMode 设置模式,默认:SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_KEEP
 *      SplDoublyLinkedList::IT_MODE_FIFO (Stack style) 先进先出
 *      SplDoublyLinkedList::IT_MODE_LIFO (Queue style) 后进先出
 *      SplDoublyLinkedList::IT_MODE_KEEP (Elements are traversed by the iterator) 遍历保留
 *      SplDoublyLinkedList::IT_MODE_DELETE (Elements are deleted by the iterator) 遍历删除
 *  setIteratorMode 设置模式不能设置为后进先出;
 *
 * 注意:仅仅遍历操作 IT_MODE_KEEP 才生效,非遍历操作(比如pop,dequeue等)是直接从队列中取出一个元素,IT_MODE_KEEP 不生效。
 */

namespace case1;

$obj = new \SplQueue();
for ($i = 1; $i <= 10; $i++) {
    $obj->enqueue($i);
}
echo "队列初始长度 : " . $obj->count() . PHP_EOL;
$obj->rewind();
foreach($obj as $v){
    echo "队列遍历 : " . $v . PHP_EOL;
}
echo "队列遍历后长度 : " . $obj->count();

/**
 * 输出:
 * 队列初始长度 : 10
 * 队列遍历 : 1
 * 队列遍历 : 2
 * 队列遍历 : 3
 * 队列遍历 : 4
 * 队列遍历 : 5
 * 队列遍历 : 6
 * 队列遍历 : 7
 * 队列遍历 : 8
 * 队列遍历 : 9
 * 队列遍历 : 10
 * 队列遍历后长度 : 10
 */

namespace case2;

$obj = new \SplQueue();
$obj->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_DELETE);
for ($i = 1; $i <= 10; $i++) {
    $obj->enqueue($i);
}
echo "队列初始长度 : " . $obj->count() . PHP_EOL;
$obj->rewind();
foreach($obj as $v){
    echo "队列遍历 : " . $v . PHP_EOL;
}
echo "队列遍历后长度 : " . $obj->count();

/**
 * 输出:
 * 队列初始长度 : 10
 * 队列遍历 : 1
 * 队列遍历 : 2
 * 队列遍历 : 3
 * 队列遍历 : 4
 * 队列遍历 : 5
 * 队列遍历 : 6
 * 队列遍历 : 7
 * 队列遍历 : 8
 * 队列遍历 : 9
 * 队列遍历 : 10
 * 队列遍历后长度 : 0
 */
<think>我们正在讨论的Maven错误是关于在构建Maven插件时,maven-plugin-plugin无法自动计算goalPrefix而要求显式指定的问题。用户现在想了解在POM中配置`<extensions>true</extensions>`的作用及其与这个错误的关系。 首先,需要明确:配置`<extensions>true</extensions>`与解决这个错误没有直接关系。因为: 1. `<extensions>true</extensions>`通常用于启用Maven的核心扩展(例如,用于自定义包装类型或仓库类型),它并不影响maven-plugin-plugin如何计算goalPrefix。 2. 这个错误的原因在于maven-plugin-plugin无法从插件artifactId推导出goalPrefix,所以必须显式指定。 但是,我们可以详细解释`<extensions>`的作用,并说明它可能出现在什么场景下,以帮助用户理解。 以下是完整回答: ### 配置`<extensions>true</extensions>`的作用 在Maven插件配置中,`<extensions>`元素用于指示Maven是否加载该插件提供的扩展(extensions)。扩展是Maven的核心扩展机制,允许插件: - 提供新的打包类型(packaging) - 提供新的仓库类型(repository) - 扩展Maven核心功能(如自定义生命周期) #### 典型应用场景 ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.6.0</version> <extensions>true</extensions> <!-- 启用扩展 --> </plugin> ``` 1. **启用自定义打包类型** 当插件定义了新的打包类型(如`maven-assembly-plugin`支持`pom`、`jar`以外的类型),需设置`<extensions>true</extensions>`激活该类型[^2]。 2. **扩展Maven核心行为** 例如`maven-shade-plugin`可通过扩展重写依赖解析逻辑(通常较少使用)。 ### 与`goalPrefix`错误的关系 **直接结论**: 配置`<extensions>true</extensions>`**无法解决**`goalPrefix`计算失败的错误。二者属于不同维度的配置: - `goalPrefix`错误源自插件元数据生成失败(`maven-plugin-plugin`执行`descriptor`目标时) - `<extensions>`用于控制插件是否作为核心扩展加载 ### 正确解决方案 回到原始错误,唯一可靠的方法是**显式指定`goalPrefix`**(如之前回答): ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.13.1</version> <configuration> <goalPrefix>custom</goalPrefix> <!-- 手动指定前缀 --> </configuration> </plugin> </plugins> </build> ``` ### 补充说明 若在插件项目中意外配置了`<extensions>true</extensions>`(通常不需要),可能导致不可预见的副作用: - 错误地尝试将插件作为扩展加载,可能干扰Maven核心 - 与`goalPrefix`错误无关,但建议移除无用配置 §§相关问题§§ 1. Maven核心扩展(extensions)和普通插件(plugins)有什么区别? 2. 如何为自定义打包类型开发Maven扩展? 3. 在哪些场景下需要避免使用`<extensions>true</extensions>`? 4. 如何验证Maven扩展是否生效? 引用说明: [^1]: 用户在引用[1]中提供了原始错误信息,明确了错误类型。 [^2]: 用户在引用[2]中给出了一段插件配置,其中未使用`<extensions>`,但该配置展示了插件执行(execution)的绑定方式,与当前话题无直接关联,故未在回答中引用。 </think>### 配置 `<extensions>true</extensions>` 的作用及与报错的关联 #### 1. **`<extensions>` 的核心作用** 在 Maven 插件配置中,`<extensions>true</extensions>` **用于启用插件的核心扩展功能**: ```xml <plugin> <groupId>com.example</groupId> <artifactId>your-plugin</artifactId> <version>1.0.0</version> <extensions>true</extensions> <!-- 关键配置 --> </plugin> ``` - **扩展机制**:允许插件修改 Maven 核心行为(如自定义生命周期、包装类型或依赖解析规则)[^2] - **生效时机**:在项目初始化阶段加载,早于常规插件执行周期 - **典型用例**: - 实现自定义打包类型(如 `war`、`zip`) - 扩展依赖管理逻辑 - 注册新的构件类型处理器 #### 2. **与 `goalPrefix` 报错的关联分析** | 配置项 | 影响范围 | 与报错的关联性 | |------------------------|----------------------------|------------------------| | **`<extensions>true`** | Maven 核心行为扩展 | ❌ 无直接关系 | | **`<goalPrefix>`** | 插件目标(Goals)标识符 | ✅ 直接解决报错的核心配置 | **关键结论**: 1. **无关性**: `goalPrefix` 报错是由于插件元数据生成失败引起的,而 `<extensions>true` 是功能扩展开关,**两者属于不同维度的配置**,添加该配置无法解决此报错[^1]。 2. **可能误用场景**: 仅当您的插件涉及以下情况时才需配置 `<extensions>true`: ```xml <!-- 正确用例:插件提供自定义打包类型 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <extensions>true</extensions> </plugin> ``` 若错误配置在普通插件上,反而可能导致: - 生命周期阶段冲突 - 构建过程异常终止 #### 3. **解决方案优先级** 正确解决 `goalPrefix` 报错的步骤: ```mermaid graph TD A[报错] --> B{检查插件命名} B -->|符合 xxx-maven-plugin 格式| C[自动推导前缀] B -->|不符合规范| D[显式配置 goalPrefix] D --> E[添加 maven-plugin-plugin 配置] E --> F[解决报错] G[添加 extensions] --> X{是否核心扩展插件?} X -->|是| H[必要配置] X -->|否| I[移除配置] ``` #### 4. **验证配置有效性** ```shell # 1. 检查插件元数据生成 mvn org.apache.maven.plugins:maven-plugin-plugin:3.13.1:descriptor # 2. 验证插件调用(使用配置的goalPrefix) mvn yourPrefix:goalName ``` ### 总结建议 - **必须配置**:通过 `<goalPrefix>` 显式指定插件前缀以解决元数据生成问题[^1] - **谨慎使用**:仅在插件提供核心扩展功能时添加 `<extensions>true` - **错误配置后果**: - 无关扩展配置会污染 Maven 核心 - 可能导致构建过程出现隐式错误
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值