它的工作方式与Go非常相似。它非常简单:不需要为您的代码编写文档,vdoc将从源代码生成它。
每个函数/类型/ const的文档必须放在声明之前:
// clearall clears all bits in the array 这里就是v的文档 fn clearall() { }
注释必须以定义的名称开头。
必须将模块概述放在模块名称后面的第一个注释中。
要生成文档,请运行
v doc path/to/module
#flag -lsqlite3 #include "sqlite3.h" struct C.sqlite3 struct C.sqlite3_stmt fn C.sqlite3_column_int(C.sqlite_stmt, int) int fn main() { path := 'sqlite3_users.db' db := &C.sqlite3{} C.sqlite3_open(path.cstr(), &db) query := 'select count(*) from users' stmt := &C.sqlite3_stmt{} C.sqlite3_prepare_v2(db, query.cstr(), - 1, &stmt, 0) C.sqlite3_step(stmt) nr_users := C.sqlite3_column_int(res, 0) C.sqlite3_finalize(res) println(nr_users) }
可以使用string(cstring)将C字符串转换为V字符串。
string(cstring)
查看socket.v以获取从V调用C代码的示例:
网站链接
您无需担心格式化代码或样式指南。vfmt负责:
v fmt file.v
建议设置编辑器,以便vfmt在每次保存时运行。
在推送代码之前始终运行vfmt。
fn read_log() { f := os.open('log.txt') defer { f.close() } ... if !ok { // defer statement will be called here, the file will be closed 这里将调用defer语句,文件将被关闭 return } ... // defer statement will be called here, the file will be closed 这里将调用defer语句,文件将被关闭 }
简单的说就是结束前会调用defer
没有垃圾收集或引用计数。V在编译期间清理它可以做的事情。例如:
fn draw_text(s string, x, y int) { ... } fn draw_scene() { ... draw_text('hello $name1', 10, 10) draw_text('hello $name2', 100, 10) draw_text(strings.repeat('X', 10000), 10, 50) ... }
字符串不会转义draw_text,因此在函数退出时会清除它们。
draw_text
实际上,前两次调用根本不会产生任何分配。这两个字符串很小,V将为它们使用预分配的缓冲区。
对于更复杂的情况,需要手动内存管理。这将很快修复。
V将在运行时检测内存泄漏并报告它们。要清理(例如)数组,请使用free()方法:
free()
numbers := [0; 1000000] ... numbers.free()
// hello.v fn hello() string { return 'Hello world' } // hello_test.v fn test_hello() { assert hello() == 'Hello world' }
所有测试函数都必须放在 * _test.v文件中,并以 test_ 开头。要运行测试,请执行 v hello_test.v 。要测试整个模块,请执行 v test mymodule 。
* _test.v
test_
v hello_test.v
v test mymodule
struct User { name string age int foo Foo [skip] // Use `skip` attribute to skip certain fields } data := '{ "name": "Frodo", "age": 25 }' user := json.decode(User, data) or { eprintln('Failed to decode json') return } println(user.name) println(user.age)
JSON现在非常流行,这就是内置JSON支持的原因。
json.decode函数的第一个参数是要解码的类型。第二个参数是JSON字符串。
V生成用于JSON编码和解码的代码。不使用运行时反射。这导致更好的性能。
并发模型与Go非常相似。
要同时运行
foo()
只需使用
go foo()
调用它。现在,它在一个新的系统线程中启动该功能。很快就会执行协同程序和调度程序。
struct Repo<T> { db DB } fn new_repo<T>(db DB) Repo<T> { return Repo<T>{db: db} } // This is a generic function. V will generate it for every type it's used with. fn (r Repo<T>) find_by_id(id int) ?T { table_name := T.name // in this example getting the name of the type gives us the table name return r.db.query_one<T>('select * from $table_name where id = ?', id) } db := new_db() users_repo := new_repo<User>(db) posts_repo := new_repo<Post>(db) user := users_repo.find_by_id(1)? post := posts_repo.find_by_id(1)?
大家都在搜