DeepSeek v3.1和DeepSeek R1在编程风格方面的区别
在发表这篇文章时,我让CSDN做AI摘要总结,结果它非但不总结,反而开始编写代码,后来经过分析,是因为我的文章开头就是“提示词”三个字,后面真的跟了一串提示词。CSDN调用的DeepSeek R1认为要他写代码,就写了。
我比较了两版程序,有两点不同。
1.parse_column函数
自己的:DeepSeek v3.1
fn parse_column(ref_str: &str) -> Option<usize> {let mut col_str = String::new();for c in ref_str.chars() {if c.is_ascii_alphabetic() {col_str.push(c);} else {break;}}if col_str.is_empty() {return None;}let mut col = 0;for c in col_str.chars() {col = col * 26 + (c.to_ascii_uppercase() as usize - 'A' as usize + 1);}Some(col - 1)
}
CSDN:DeepSeek R1
fn parse_column(r: &str) -> Option<usize> {r.chars().take_while(|c| c.is_alphabetic()).fold(0, |acc, c| acc * 26 + (c.to_ascii_uppercase() as usize - 'A' as usize + 1)).checked_sub(1)
}
我把上述代码让DeepSeek分析,他的结论
是的,CSDN网站上的 parse_column
函数与我们的同名函数是完全等价的。
功能分析:
两个函数都实现了相同的功能:
- 从类似 “A1”、“B3” 这样的单元格引用中提取字母列标识部分
- 将字母列标识转换为从0开始的列索引(A=0, B=1, …, Z=25, AA=26, 等等)
代码对比:
您的版本:使用显式循环和字符串构建
CSDN版本:使用函数式编程风格
等价性证明:
- 字符提取:
take_while(|c| c.is_alphabetic())
等价于您的第一个循环 - 列计算:
fold
操作等价于您的第二个循环 - 索引调整:
checked_sub(1)
等价于您的Some(col - 1)
- 空值处理:如果输入为空,
checked_sub(1)
会返回None
,与您的版本行为一致
CSDN版本的代码更加简洁和函数式,但两个版本的功能是完全相同的。
我用函数式写法函数替换了原有的,确实效果完全相同。
2.调用parse_column函数
自己的:DeepSeek v3.1
if let Some(c_ref) = cell_ref {if let Some(col) = parse_column(&c_ref) {while current_cells.len() <= col {current_cells.push(None);}current_cells[col] = cell_value;}}
CSDN
if let (Some(c_ref), Some(col)) = (cell_ref, cell_ref.as_ref().and_then(parse_column)) {while current_cells.len() <= col {current_cells.push(None);}current_cells[col] = cell_value;}
这个DeepSeek的解释虽然头头是道,
错误原因:
cell_ref 的类型是Option<String>
cell_ref.as_ref() 返回Option<&String>
(对String的引用)
and_then(parse_column) 尝试将&String
传递给 parse_column
但 parse_column 期望的是&str
,而不是&String
他给出的修复方案都行不通,就不贴出来了。
感觉R1的代码更新潮但有问题,v3的代码传统但是保险。