昨天DeepSeek按我的中文描述给出的C语言程序一举成功。相信它翻译应该比从头写容易做对,因此输入提示词:
把上述c语言程序翻译成v语言
他给出了如下的程序:
c
import os
const max_lines = 1_000_000 // 最多100万行
fn compare_offsets(a &string, b &string) int {
return *a.strcmp(*b)
}
fn main() {
if os.args.len != 2 {
eprintln('Usage: ${os.args[0]} <filename>')
exit(1)
}
filename := os.args[1]
// 读取文件内容
buf := os.read_file(filename) or {
eprintln('Failed to read file: $err')
exit(1)
}
mut lines := []&char{cap: max_lines}
mut line_start := unsafe { &char(buf.str) }
// 记录每行起始地址并将\n替换为\0
for i in 0 .. buf.len {
if buf[i] == `\n` {
unsafe {
mut p := &char(buf.str) + i
*p = `\0`
if i + 1 < buf.len {
lines << p + 1
}
}
}
}
// 添加第一行
lines << unsafe { &char(buf.str) }
// 对行指针数组进行排序
lines.sort_with_compare(compare_offsets)
// 输出排序后的行
for line in lines {
println(unsafe { line.vstring() })
}
}
但是这个程序编译有错,主要是:
bash
1.不知道string.strcmp这个方法
sortlines.v:6:15: error: unknown method or field: `string.strcmp`.
Did you mean `str`?
4 |
5 | fn compare_offsets(a &string, b &string) int {
6 | return *a.strcmp(*b)
| ~~~~~~~~~~
7 | }
8 |
2.赋值需要字符,而不是rune(用两个反单引号括起来的)
sortlines.v:31:22: error: cannot assign to `*p`: expected `char`, not `rune`
29 | unsafe {
30 | mut p := &char(buf.str) + i
31 | *p = `\0`
| ~~~~
32 | if i + 1 < buf.len {
33 | lines << p + 1
3.sort_with_compare函数的参数类型错误
sortlines.v:5:22: error: sort_with_compare callback function parameter `a` with type `&string` should be `&&char`
3 | const max_lines = 1_000_000 // 最多100万行
4 |
5 | fn compare_offsets(a &string, b &string) int {
| ~~~~~~~
6 | return *a.strcmp(*b)
7 | }
通过查阅文档,知道v语言有个compare_strings
函数,但是它的参数是string
, 参考后面输出打印语句中的println(unsafe { line.vstring() })
,所以把compare_offsets
函数改成如下,解决了第1和第3个错误:
c
fn compare_offsets(a &&char, b &&char) int {
a1:=unsafe { a.vstring() }
b1:=unsafe { b.vstring() }
return compare_strings(a1, b1)
}
第二个错误,我先后用单引号,双引号去括\0
,结果都说它是字符串,不是字符,用byte(0), 说已作废,请改用u8, 改成u8(0),编译通过。
刚开始学V语言,几点感受:
1.属于学c语言,但改得乱七八糟,不如java学c学得好;
2.编译速度很快,和c差不多,比什么zig快多了,但是编出来的二进制文件运行很慢,100万行文本排序要6秒,不排序纯复制也有4秒多;
3.依赖太多,我想用它自带的翻译功能,结果报错。
bash
v translate sort_lines.c
C2V is not installed. Cloning C2V to C:\Users\lt\.vmodules\c2v ...
Failed to download C2V.
自己下载了c2v源码编译,编译成功,执行出错,如下:
bash
C:\d\c2v\src>vwin\v\v .
C:\d\c2v\src>src
V panic: cannot find clang in PATH
v hash: a5f9899
C:/Users/lt/AppData/Local/Temp/v_0/src.01K1JRA7HG175MNMCF035ZZ6SM.tmp.c:9471: at _v_panic: Backtrace
C:/Users/lt/AppData/Local/Temp/v_0/src.01K1JRA7HG175MNMCF035ZZ6SM.tmp.c:20076: by main__find_clang_in_path
C:/Users/lt/AppData/Local/Temp/v_0/src.01K1JRA7HG175MNMCF035ZZ6SM.tmp.c:24096: by _vinit
C:/Users/lt/AppData/Local/Temp/v_0/src.01K1JRA7HG175MNMCF035ZZ6SM.tmp.c:24110: by wmain
00544e40 : by ???
00544fa3 : by ???
7fff3610e8d7 : by ???
竟然还要依赖clang。
4.有一个像python那样的CLI,还挺漂亮的,可以单独解释执行某个语句。
bash
C:\d>vwin\v\v
____ ____
\ \ / / | Welcome to the V REPL (for help with V itself, type exit , then run v help ).
\ \/ / | Note: the REPL is highly experimental. For best V experience, use a text editor,
\ / | save your code in a main.v file and execute: v run main.v
\ / | V 0.4.11 a5f9899 . Use list to see the accumulated program so far.
\__/ | Use Ctrl-C or exit to exit, or help to see other available commands.
>>> 'DEF'.split('')
['D', 'E', 'F']
>>> 'DEF'.runes()
[`D`, `E`, `F`]
但是,作为通用语言,学习成本太高了,学会了也没什么用。