简单直接的方法
1.将int数组转换成一个字符串
2.定义一个新数组长度是字符串的长度
3.用chartAt方法取出每一个下标下的char转为数字塞进新数组里
![]()
1.将int数组转换成一个字符串
2.定义一个新数组长度是字符串的长度
3.用chartAt方法取出每一个下标下的char转为数字塞进新数组里
![]()
给你一个正整数数组 nums ,请你返回一个数组 answer ,你需要将 nums 中每个整数进行数位分割后,按照 nums 中出现的 相同顺序 放入答案数组中。
对一个整数进行数位分割,指的是将整数各个数位按原本出现的顺序排列成数组。
10921 ,分割它的各个数位得到 [1,0,9,2,1] 。
示例 1:
输入:nums = [13,25,83,77] 输出:[1,3,2,5,8,3,7,7] 解释: - 分割 13 得到 [1,3] 。 - 分割 25 得到 [2,5] 。 - 分割 83 得到 [8,3] 。 - 分割 77 得到 [7,7] 。 answer = [1,3,2,5,8,3,7,7] 。answer 中的数字分割结果按照原数字在数组中的相同顺序排列。
示例 2:
输入:nums = [7,1,3,9] 输出:[7,1,3,9] 解释:nums 中每个整数的分割是它自己。 answer = [7,1,3,9] 。
提示:
1 <= nums.length <= 10001 <= nums[i] <= 105这道题要求将给定的正整数数组 $\textit{nums}$ 中的所有正整数按数位分割,保持数位顺序存入答案数组。需要首先遍历数组 $\textit{nums}$ 得到数位总数,然后将每个正整数按数位分割并存入答案数组。
首先遍历数组 $\textit{nums}$ 得到所有正整数的数位总数 $\textit{totalLength}$,然后创建长度为 $\textit{totalLength}$ 的答案数组 $\textit{answer}$,再次遍历数组 $\textit{nums}$,遍历过程中维护答案数组的当前下标 $\textit{index}$,对于每个正整数,执行如下操作。
用 $\textit{start}$ 表示当前正整数的数位填入答案数组的起始下标,$\textit{start} = \textit{index}$。
每次将 $\textit{num}$ 的最低位填入 $\textit{answer}[\textit{index}]$,然后将 $\textit{index}$ 的值增加 $1$,重复该操作直到 $\textit{num}$ 的所有位都填入答案数组。
当前正整数 $\textit{num}$ 填入答案数组的下标范围是 $[\textit{start}, \textit{index} - 1]$,为按照数位从低到高的顺序填入。为了和数组 $\textit{nums}$ 中的数位顺序保持一致,需要将答案数组的下标范围 $[\textit{start}, \textit{index} - 1]$ 的子数组翻转。
遍历结束之后,即可得到答案数组。
###Java
class Solution {
public int[] separateDigits(int[] nums) {
int totalLength = 0;
for (int num : nums) {
totalLength += getLength(num);
}
int[] answer = new int[totalLength];
int index = 0;
for (int num : nums) {
int start = index;
int temp = num;
while (temp != 0) {
answer[index] = temp % 10;
index++;
temp /= 10;
}
reverse(answer, start, index - 1);
}
return answer;
}
public int getLength(int num) {
int length = 0;
while (num != 0) {
length++;
num /= 10;
}
return length;
}
public void reverse(int[] answer, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
int temp = answer[i];
answer[i] = answer[j];
answer[j] = temp;
}
}
}
###C#
public class Solution {
public int[] SeparateDigits(int[] nums) {
int totalLength = 0;
foreach (int num in nums) {
totalLength += GetLength(num);
}
int[] answer = new int[totalLength];
int index = 0;
foreach (int num in nums) {
int start = index;
int temp = num;
while (temp != 0) {
answer[index] = temp % 10;
index++;
temp /= 10;
}
Reverse(answer, start, index - 1);
}
return answer;
}
public int GetLength(int num) {
int length = 0;
while (num != 0) {
length++;
num /= 10;
}
return length;
}
public void Reverse(int[] answer, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
int temp = answer[i];
answer[i] = answer[j];
answer[j] = temp;
}
}
}
###C++
class Solution {
public:
vector<int> separateDigits(vector<int>& nums) {
int totalLength = 0;
for (int num : nums) {
totalLength += getLength(num);
}
vector<int> answer(totalLength);
int index = 0;
for (int num : nums) {
int start = index;
int temp = num;
while (temp != 0) {
answer[index] = temp % 10;
index++;
temp /= 10;
}
reverse(answer, start, index - 1);
}
return answer;
}
int getLength(int num) {
int length = 0;
while (num != 0) {
length++;
num /= 10;
}
return length;
}
void reverse(vector<int>& answer, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
swap(answer[i], answer[j]);
}
}
};
###Python
class Solution:
def separateDigits(self, nums: List[int]) -> List[int]:
answer = []
index = 0
for num in nums:
start = index
temp = num
while temp != 0:
answer.append(temp % 10)
index += 1
temp //= 10
self.reverse(answer, start, index - 1)
return answer
def getLength(self, num: int) -> int:
length = 0
while num != 0:
length += 1
num //= 10
return length
def reverse(self, answer: List[int], start: int, end: int) -> None:
i, j = start, end
while i < j:
answer[i], answer[j] = answer[j], answer[i]
i += 1
j -= 1
###C
int getLength(int num) {
int length = 0;
while (num != 0) {
length++;
num /= 10;
}
return length;
}
void reverse(int* answer, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
int temp = answer[i];
answer[i] = answer[j];
answer[j] = temp;
}
}
int* separateDigits(int* nums, int numsSize, int* returnSize) {
int totalLength = 0;
for (int i = 0; i < numsSize; i++) {
totalLength += getLength(nums[i]);
}
int* answer = (int*) malloc(sizeof(int) * totalLength);
*returnSize = totalLength;
int index = 0;
for (int i = 0; i < numsSize; i++) {
int start = index;
int temp = nums[i];
while (temp != 0) {
answer[index] = temp % 10;
index++;
temp /= 10;
}
reverse(answer, start, index - 1);
}
return answer;
}
###Go
func separateDigits(nums []int) []int {
totalLength := 0
for _, num := range nums {
totalLength += getLength(num)
}
answer := make([]int, totalLength)
index := 0
for _, num := range nums {
start := index
temp := num
for temp != 0 {
answer[index] = temp % 10
index++
temp /= 10
}
reverse(answer, start, index - 1)
}
return answer
}
func getLength(num int) int {
length := 0
for num != 0 {
length++
num /= 10
}
return length
}
func reverse(answer []int, start int, end int) {
for i, j := start, end; i < j; i, j = i + 1, j - 1 {
answer[i], answer[j] = answer[j], answer[i]
}
}
###JavaScript
var separateDigits = function(nums) {
let totalLength = 0;
for (let num of nums) {
totalLength += getLength(num);
}
let answer = new Array(totalLength);
let index = 0;
for (let num of nums) {
let start = index;
let temp = num;
while (temp !== 0) {
answer[index] = temp % 10;
index++;
temp = Math.floor(temp / 10);
}
reverse(answer, start, index - 1);
}
return answer;
};
var getLength = function(num) {
let length = 0;
while (num !== 0) {
length++;
num = Math.floor(num / 10);
}
return length;
};
var reverse = function(answer, start, end) {
for (let i = start, j = end; i < j; i++, j--) {
let temp = answer[i];
answer[i] = answer[j];
answer[j] = temp;
}
};
###TypeScript
function separateDigits(nums: number[]): number[] {
let totalLength = 0;
for (let num of nums) {
totalLength += getLength(num);
}
let answer = new Array(totalLength);
let index = 0;
for (let num of nums) {
let start = index;
let temp = num;
while (temp !== 0) {
answer[index] = temp % 10;
index++;
temp = Math.floor(temp / 10);
}
reverse(answer, start, index - 1);
}
return answer;
};
function getLength(num: number): number {
let length = 0;
while (num !== 0) {
length++;
num = Math.floor(num / 10);
}
return length;
};
function reverse(answer: number[], start: number, end: number): void {
for (let i = start, j = end; i < j; i++, j--) {
let temp = answer[i];
answer[i] = answer[j];
answer[j] = temp;
}
};
时间复杂度:$O(n \log_{10} m)$,其中 $n$ 是数组 $\textit{nums}$ 的长度,$m$ 是数组 $\textit{nums}$ 的最大元素。计算答案数组的长度与将数位填入答案数组的时间是 $O(n \log_{10} m)$。
空间复杂度:$O(1)$。注意返回值不计入空间复杂度。
这个刚开始写的时候担心数组的长度和时间复杂度的原因,担心通过不了,结果没想过通过了。
我是用一个result数组来装将返回的分割数位值,考虑他们的长度,每一个元素的大小在10的五次方以内,分割之后100000共有六位,也就是最大是6,加上数组的长度最大是1000,于是我就把数组的大小取为6*10000=60000.
虽然我也知道浪费空间,但是我目前没有更好的方法,希望有大佬能够指点。
确定了返回数组了,然后就是然后把原始的整数拆分插入到结果数组中,后面我想到只要逐个不断求余就可以得到每一位数,后面我就在第一层遍历中添加一个循环得到整数的各个数位,但是提交的结果不符合要求,题目要求将数位按原本出现的顺序排列成数组,于是我就用一个数组作为辅助空间,将它反向添加,于是就得到了和题目意思相同的结果,辅助空间的大小就是一个整数拥有的各个位数的数量,由前面可以知道最大是6。
之后返回即可。
int* separateDigits(int* nums, int numsSize, int* returnSize){
int *result=(int*)malloc(sizeof(int)*60000);
int count=0;
//遍历整个数组
for(int i=0;i<numsSize;i++){
int tmp=nums[i];
int help[6];
int tmpCount=0;
//得到整数的各个数位,将他们储存在一个辅助数组中
while(tmp){
help[tmpCount++]=tmp%10;
tmp=tmp/10;
}
//把数组中的元素倒序添加到结果数组中
for(int j=tmpCount-1;j>=0;j--){
result[count++]=help[j];
}
}
*returnSize=count;
return result;
}
把 $\textit{nums}[i]$ 转成字符串,即可从高到低遍历数位。
class Solution:
def separateDigits(self, nums: List[int]) -> List[int]:
return [int(ch) for x in nums for ch in str(x)]
class Solution {
public int[] separateDigits(int[] nums) {
List<Integer> digits = new ArrayList<>();
for (int x : nums) {
for (char ch : String.valueOf(x).toCharArray()) {
digits.add(ch - '0');
}
}
int m = digits.size();
int[] ans = new int[m];
for (int i = 0; i < m; i++) {
ans[i] = digits.get(i);
}
return ans;
}
}
class Solution {
public:
vector<int> separateDigits(vector<int>& nums) {
vector<int> ans;
for (int x : nums) {
for (char ch : to_string(x)) {
ans.push_back(ch - '0');
}
}
return ans;
}
};
func separateDigits(nums []int) (ans []int) {
for _, x := range nums {
for _, ch := range strconv.Itoa(x) {
ans = append(ans, int(ch-'0'))
}
}
return
}
不断地把 $n$ 除以 $10$(下取整)直到 $0$,例如 $123\to 12\to 1\to 0$。在这个过程中的 $n\bmod 10$,即为每个数位。
这样做是从低到高遍历数位,和题目要求的顺序相反。
我们可以从右到左遍历 $\textit{nums}$,从低到高遍历 $\textit{nums}[i]$ 的数位。最后把遍历过的数位反转,即为答案。
class Solution:
def separateDigits(self, nums: list[int]) -> list[int]:
ans = []
for x in reversed(nums):
while x > 0:
ans.append(x % 10)
x //= 10
ans.reverse()
return ans
class Solution {
public int[] separateDigits(int[] nums) {
List<Integer> digits = new ArrayList<>();
for (int i = nums.length - 1; i >= 0; i--) {
for (int x = nums[i]; x > 0; x /= 10) {
digits.add(x % 10);
}
}
int m = digits.size();
int[] ans = new int[m];
for (int i = 0; i < m; i++) {
ans[i] = digits.get(m - 1 - i);
}
return ans;
}
}
class Solution {
public:
vector<int> separateDigits(vector<int>& nums) {
vector<int> ans;
for (int x : nums | views::reverse) {
for (; x > 0; x /= 10) {
ans.push_back(x % 10);
}
}
ranges::reverse(ans);
return ans;
}
};
func separateDigits(nums []int) (ans []int) {
for _, x := range slices.Backward(nums) {
for ; x > 0; x /= 10 {
ans = append(ans, x%10)
}
}
slices.Reverse(ans)
return
}
欢迎关注 B站@灵茶山艾府
This is a major release.
Feature highlights✨:
cli/purge.php to apply purge policy from command lineBug fixes highlights 🐛:
Security highlights 🛡:
UI highlights 🖼:
Extensions highlights 🧩:
This release has been made by @Alkarex, @Inverle, @Kiblyn11, @math-GH, @rupakbajgain, @xtmd and newcomers @polybjorn, @olivluca, @tomasodehnal, @PeterVavercak, @mrtnrdl, @ale-rt, @cweiske, @rid3r45, @gabbihive, @drosell271, @Kachelkaiser, @zanivann, @nanos, @bowencool, @pe1uca, @matheusroberson, @DenuxPlays, @rlrs, @chanse-syres, @IEEE-754, @umaidshahid, @michi-onl
Full changelog:
mdate:P1D for finding articles modified by the author / server during the past day.toString in case of regex-looking string #8479
<iframe> referrer allow list #8672
allowfullscreen to <iframe> #8467
Set-Cookie using native PHP support of SameSite #8447, #8778
session.cookie-lifetime in php.ini
<meta name="referrer" content="no-referrer" /> from deprecated never #8725
.content pre code #8620
Minz_HookType::ActionExecute #8599, #8603
Minz_HookType as hook name in registerHook() #8600
httpGet() #8700
httpGet() cache nullable #8705
select-input-changer JavaScript helper #8721
get_icon_url() for feed favicon simplepie#974
get_thumbnail() #8634, simplepie#970
cli/purge.php to apply purge policy #8740
timeago() #8670
AGENTS.md, SKILLS.md, instructions.md #8478
你也可以为这个项目出一份力,如果发现有价值的信息、文章、工具等可以到 Issues 里提给我们,我们会尽快处理。记得写上推荐的理由哦。有建议和意见也欢迎到 Issues 提出。
@Kyle-Ye: DanceUI 是 ByteDance 开源的类 SwiftUI 声明式 UI 框架,目标是在 SwiftUI 风格的 DSL 和更低系统版本兼容之间做一层工程化实现。项目提供了与 SwiftUI 对齐的基础能力,包括 State、Binding、Environment、PreferenceKey、NavigationView、ScrollView 等,同时通过 DanceUIRuntime、DanceUIGraph、OpenCombine 和 DanceUIObservation 相关模块支撑状态更新与渲染链路。整体预期是可以直接复用 SwiftUI 生态且最低支持 iOS 13。
@Cooper Chen:以这篇文章《Trust, Then Verify》开头,你会很快意识到 : 真正拉开 AI 编程差距的,不是“写得快”,而是“能自证”。作者围绕 iOS 场景搭建了一套完整验证闭环 : 构建侧用 xcodebuild + xcbeautify 控噪并保留原始日志兜底,交互侧用 AXe 与 simctl 将启动、点击、读值、断言流程脚本化,让 Agent 从“像是对了”走向“可验证地对了”。更可贵的是文中沉淀出的工程方法论 : 入口宽松、断言严格;在最靠近原因的位置让失败可见;把经验性步骤持续机械化;通过使用驱动迁移而非一次性大审计。对 iOS 团队和所有实践 Agentic Coding 的开发者来说,这篇文章都值得细读。
@zhangferry:Anthropic 的成功不能简单归功于 Claude Code、Co-Work 这类明星级产品,而是应该着重关注这类产品迭代背后的方法论。这篇文章的访谈嘉宾 Cat Woo 是 Claude Code 和 Co-work 的产品负责人,她系统性地分享了 Claude Code 团队的实战经验。他们的产品是 AI,他们的工作方式也因为 AI 被全面重塑;访谈涵盖了一个核心命题:当模型能力每隔几个月就跃升一次,产品经理的角色该如何重新定义?
@david-clang:为什么 .pbxproj 容易臃肿和冲突?因为它记录了所有文件的 UUID,而使用 Groups 会让 Xcode 追踪每一个文件变动。文章介绍的解决办法很简单,用 Folders 代替 Groups,Xcode 只引用目录,不追踪单文件。另外,使用 XcodeGen 也能解决,它将 .xcodeproj 移出 Git,全靠本地按需生成,实现零冲突。
@Barney:David Smith 在这篇文章里复盘了 Pedometer++ 为 watchOS 打磨地图体验的六年历程,内容很适合拿来理解小屏设备上的产品设计为什么往往是工程能力、交互约束和视觉语言一起决定的。作者最初用服务端生成地图验证方向,随后因为离线能力、性能和交互需求,转向自研基于 SwiftUI 的地图渲染引擎;在界面层面,则经历了大量失败方案,最终收敛到“地图作为顶部主页面,指标信息层叠覆盖”的结构,并通过点击进入浏览模式来解决地图交互与 watchOS 手势冲突。文章后半段也很有意思:为了适配 watchOS 26 的 Liquid Glass,他甚至定制了新的底图与深色模式样式,并解释了为什么最终没有直接采用 MapKit。整体来看,这是一篇把平台限制、设计迭代和技术取舍讲得非常完整的实战复盘。
@Smallfly:这篇是 Swift 并发同步机制的深度指南,系统对比四类核心同步工具的设计哲学、适用场景与权衡取舍,为开发者构建线程安全代码提供全面决策框架。文章从语言级到硬件级逐层拆解各工具特性:Actors 适合异步环境下的缓存、服务类等状态组件,DispatchQueue 适配依赖执行上下文协调的场景,Locks/Mutexes 性能开销低适合同步小操作,Atomics 则适配计数器、状态标志等单操作场景。文中还给出各工具典型误用的修复方案,打破性能优先的误区,综合安全性、API 设计清晰度、认知负荷等维度给出选择指导,通过场景化分析与可运行示例,帮助开发者理解 Swift 并发同步本质,在复杂系统中做出合理技术选择。
@阿权:Cupertino MCP 发布 v1.0.0 "First Light" 版本。Cupertino 是一款本地 Apple 文档爬虫 MCP,使用 Swift 编写。用于解决 LLM 对 Apple API 回答幻觉问题,让模型推理时能获取精准、排名合理的 Apple 官方文档,本次版本实现了全流程(爬取、索引、排名、服务、分发)稳定,具体如下:
重新开始更新「iOS 靠谱内推专题」,整理了最近明确在招人的岗位,供大家参考
具体信息请移步:https://www.yuque.com/iosalliance/article/bhutav 进行查看(如有招聘需求请联系 iTDriverr)
我们是「老司机技术周报」,一个持续追求精品 iOS 内容的技术公众号,欢迎关注。
关注有礼,关注【老司机技术周报】,回复「2024」,领取 2024 及往年内参
同时也支持了 RSS 订阅:https://github.com/SwiftOldDriver/iOS-Weekly/releases.atom 。
🚧 表示需某工具,🌟 表示编辑推荐
预计阅读时间:🐎 很快就能读完(1 - 10 mins);🐕 中等 (10 - 20 mins);🐢 慢(20+ mins)
4 月 25 日上午 10 点 08 分,华为 Pura X Max 正式开售。10999 元起步,12999 元的典藏版比标准版贵 2000 元。
十天之后,第三方监测数据公布了更多细节——典藏版占首销总量的 55%,标准版只占 45%。
越贵的版本,反而卖得更多。
这是 2026 年上半年中国手机市场少见的反常画面。同一时段里,整个行业的基调是「涨价、收缩、分化」——但一台万元起步的折叠屏旗舰,不仅卖爆了,而且越贵的型号卖得越好。
余承东在北京车展上的原话是「卖爆了」。随后有媒体援引华为内部数据:首销日激活 7 万+、3 天 11 万+、7 天 17 万+、10 天 20 万+,每一档都是折叠屏品类的历史最高。
![]()
华为 Pura X Max|图片来源:极客公园
这台机器是华为口中的「行业首款横向阔折叠」。余承东在发布会上把它的形态正式命名为「阔折叠」。
但比起单纯堆数据,我更想搞清楚一件事:Pura X Max 卖爆了,是不是意味着「阔折叠」这个形态被市场认可了?
这两件事看起来是一回事,其实不是。
01
反常的不是绝对值
首销十天 20 万台,这个绝对值放在整个智能手机市场,并不算骇人——同期任何一款主流直板旗舰首销都能超过它。
数据反常的地方是相对值。
据博主 @RD观测 的数据,Pura X Max 首销日的销量约为 Pura X 同期的 215%,首周是 180%。截至 5 月 4 日,较 Mate X7 同期提升 61%,较 Pura X 同期提升 45%。
Mate X7 是华为 2025 年 11 月发布的横向大折叠旗舰,是华为传统折叠屏的「重型」产品线,定价段位高于 Pura X 系列。Pura X Max 在它面前 +61%——这意味着 Pura X Max 其实已经在蚕食华为自家的传统折叠屏需求池。
它在吸引新用户的同时,也从 Mate X7 手里挖走了相当一部分原本会选 Mate X7 的老用户。
而典藏版 55% 的占比则给出了另一个信号——这群肯多花 2000 块的用户,不是在「冲销量」,他们认这台机器,并且愿意为更完整的版本付溢价。在 2026 年这个高端机型普遍「涨价遇冷」的市场里,这种价格分布反常本身就是一个独立的产品力背书。
![]()
华为 Pura X Max |图片来源:极客公园
把绝对值(20 万台)、相对值(+61% / +45%)、内部蚕食(vs Mate X7)、价格分布(典藏版 55%)这四组数据摆在一起,结论其实很清楚:Pura X Max 这台产品本身是成功的。
把镜头从 Pura X Max 这台机器拉远一点:2026 年的折叠屏市场,目前在售的「阔折叠」产品只有一款:华为 Pura X Max。它的前代 Pura X,是另一款阔折叠产品,但已经接近停产周期。三星、苹果、OPPO、vivo、小米、荣耀,目前没有任何一家厂商在卖同形态产品。
这意味着一件事——Pura X Max 的销量再高,能证明的也只是「华为做阔折叠行」,而不是「阔折叠这个形态行」。
一个形态如果只有一个玩家在卖,无论卖得多好,都还不能叫品类共识。
02
用户、同行与苹果
用户层面「用钱投票」认可,是过去一年最确定的部分。
IDC 的数据显示,截至 2026 年 3 月底,上市一年间,华为 Pura X 出货量突破 150 万台,单款产品出货量超过其后三位厂商旗舰折叠机型产品的总和。
这是一个跨越式的数字。在折叠屏整体仍是个低个位数比例的小众市场里(折叠屏占整体智能手机出货比例至今未突破 5%),一款单品做到这个量,意味着 Pura X 抓住了一个真实存在的用户群。
我之前写过一篇关于 Pura X Max 的稿子,里面提到一个细节:在 Pura X 上市之后,小红书上慢慢沉淀出一种特殊的用法——主要是女性用户,她们买了 Pura X 之后,会再配一个固定硬壳,把它常态锁在展开状态下使用,几乎不合上。
简单说,就是把这台一万元的折叠屏,当成一台屏幕比例特殊的直屏机来用。
这件事的反讽意味在于——折叠屏过去七年的核心叙事,是「同一台设备的两种形态」「手机和平板二合一」。所有厂商的发布会上,最高光的镜头永远是机身合起或打开的那个瞬间。
但 Pura X 的部分用户用脚投票投出来的结论是:他们要的不是「二合一」,是那块比例对的大屏。
Pura X Max 在这群人的基础上,又往前走了一步——把内屏从手机的边界推过了平板的边界(7.7 英寸,已经接近 iPad mini 的 8.3 英寸)。所以 Pura X Max 首销 +45% 这个数字背后,其实是 Pura X 时代的用户在升级,加上一批被 Pura X 验证之后才决定下场的新用户。
同行层面的情况,比用户层面复杂得多。
跟得最明确的是三星。据 ET News 在 2025 年底的报道,三星正在开发一款代号 Wide Fold 的产品,计划 2026 年秋季推出,展开后是 7.6 英寸 4:3 比例的内屏,折叠后是 5.4 英寸外屏。
![]()
三星版「阔折叠」屏幕比例与 Pura X Max 高度相似|图片来源:UniverseIce
这个参数和 Pura X Max 的形态高度重合——三星这次没有继续走传统的 Z Fold 路线,而是单独开了一条阔折叠产品线。
这是过去七年里,三星折叠屏战略上的一次显著调整。
但除了三星之外,其他主要厂商目前都还在「计划」「传闻」阶段。
在 2025 年底曾行业消息称,OPPO、vivo、小米、荣耀都计划在 2026 年推出阔折叠手机。但截至目前,这些产品没有一款落地。如今我们真正看到的「阔折叠」,还只有 Pura X Max 一款
OV 米荣这种「先观望、再下场」的姿态,在中国手机厂商里并不少见,本身是一个理性的商业选择——但它也意味着,目前还没有哪一家国产厂商,敢像三星那样,把自己未来 12 个月的旗舰押在阔折叠这个形态上。
同行这一票,三星投了,但 OV 米荣还在观望。所以最多算半票。
最关键的那一票,是苹果。
天风国际证券分析师郭明錤在过去一年里多次披露苹果折叠 iPhone 的供应链信息。最关键的一条是关于形态的:这台代号为 iPhone Fold 的产品,走的是 book-style 左右开,不是阔折叠。
![]()
折叠屏 iPhone 与一开始预期的「阔折叠」实际尺寸上有明显差距|图片来源:macrumors
具体形态是——折叠时外屏 5.5 英寸(接近常规手机比例),展开时内屏 7.8 英寸(接近正方形)。这种形态接近三星传统的 Galaxy Z Fold 系列,本质是「左右翻书」,而不是华为这种「平板对折成横向大屏」。
苹果的产品节奏,目前供应链口径是 2026 年下半年发布、但因为开发滞后,量产可能要拖到 2027 年。Counterpoint 预测苹果折叠 iPhone 首批出货量在 800 万到 1000 万台之间,2027 年扩大到 2000 万。
这个量级会迅速重新定义整个折叠屏市场的竞争格局。
但这里有一个常被忽略的事实:苹果这台机器的形态选择,不是「阔折叠」,而是 book-style。 也就是说,折叠屏市场里量级最重、品牌号召力最强、最有可能定义品类标准的那个玩家,没有把票投给阔折叠。
这一票不是反对,是弃权——苹果选了另一条路。
而苹果选的这条路,意味着另一种叙事:折叠屏是一台「能展开的手机」,不是一台「能装进口袋的小平板」。
哪种叙事会赢?现在没有答案。
03
答案是「一半」
把三票放在一起看,「阔折叠是否被认可」这个问题的答案就清楚了:用户层面赢了,同行层面赢了一半,对手层面没投票。
加起来,是一半的胜利。
这一半的胜利,足够让 Pura X Max 在 2026 年的窗口期里独自领跑——目前阔折叠形态没有第二个在售对手,它在这条路上是唯一的玩家,销量和用户教育都做得起来。但要把这一半补成完整的胜利,需要在接下来 12 到 18 个月里发生两件事:
第一,三星 2026 年秋季的 Wide Fold 真的落地,并且销量能跟上。如果三星这台机器卖得好,「阔折叠」就有了第二个独立验证的玩家,OV 米荣会迅速跟进。
第二,苹果在 2027 年的折叠 iPhone 之后,是不是会推出第二代——而第二代的形态选择是不是会向阔折叠靠拢。 苹果第一代选 book-style 是供应链、铰链工艺、生态适配的综合考量,第二代有调整空间。如果 2028 年苹果出一款 √2:1 比例的折叠 iPhone,那「阔折叠」就有了真正的品类共识。
这两件事如果都发生,Pura X Max 在 2026 年这个时间点,会被记成华为「定义阔折叠并赢下整个赛道」的起点。如果只发生一件,它仍然是 2026 年最成功的折叠屏,但「阔折叠 = 折叠屏下一代」这个命题成立的可能性会被打折。
![]()
华为 Pura X Max|图片来源:极客公园
所以现在能下的判断只有这一句:阔折叠在用户层面赢了,在同行层面赢了一半,在最重要的玩家那里还没拿到票。 销量数据说明华为的产品力没有问题,但形态层面的胜负还没有终局答案。
要等到 2026 年底回头看——三星 Wide Fold 卖得怎么样、OV 米荣有没有跟进、以及苹果 iPhone Fold 的市场反应是什么——才能真正判断这一半的胜利能不能补成完整的一票。