V语言12配置包
#pkgconfig
.告诉编译器用配置
文件来编译/链接
模块.
只要#flag
中不用反引号
及为了安全/可移植
不产生进程,V
用自己的pkgconfig
库.其与标准freedesktop
匹配.未传递标志,则自动加--cflags和--libs
.下两行意思一样.
#pkgconfig r_core
#pkgconfig --cflags --libs r_core
在默认的pkg-config
路径列表中查找.pc
文件,用户也可用PKG_CONFIG_PATH
环境变量来加.可传递多个模块.
直接包含C代码
假设你的V
模块中有个C目录,根目录下放个v.mod
,内容为:
Module {
name: "mymodule",
description: "包装C库",
version: "0.0.1"
dependencies: []
}
模块中加上:
#flag -I @VMODROOT/c
#flag @VMODROOT/c/implementation.o
//查找o文件来连接,否则假定有相应c文件,再编译链接
#include "header.h"
@VMODROOT
替换为最近父目录
.@VMODROOT
目录也预先加至查找模块路径
.在@VMODROOT
目录下,其他模块,也直接用名字导入即可.可见示例
.
C类型
普通C串转为V串:unsafe { &char(cstring).vstring() }
,知道长度:unsafe { &char(cstring).vstring_with_len(len) }
.
注意:.vstring()和.vstring_with_len()
并不复制c串
,不要释放
它.用cstring_to_vstring(cstring)
来复制c串
.
窗口
中,c串用宽串
:string_from_wide(&u16(cwidestring))
.
V类型 | 等价C类型 |
---|---|
voidptr | void* , |
&byte | byte* |
&char | char* |
&&char | char** |
转换空针
至V引用
:user := &User(user_void_ptr)
.
解引用:voidptr
,用user := User(user_void_ptr)
.
C标识符
通过C前缀
来访问,在V
中必须先声明才能使用.C类型
必须在C前缀
后用.重声明是为了访问类型成员
.像这样重声明类型:
struct SomeCStruct {//C构
uint8_t implTraits;
uint16_t memPoolData;
union {
struct {
void* data;
size_t size;
};
DataView view;
};
};
子数据结构成员,必须直接声明:
struct C.SomeCStruct {//声明为这样
implTraits byte
memPoolData u16
//目前不能直接用V表示
data voidptr
size size_t//为了效率,直接声明.
view C.DataView
}
V知道存在数据成员
,这样不必再重建.你可嵌入子结构
来维护并行代码结构.
调试
用-b c
.你传递标志.
标志 | 意思 |
---|---|
-g | 较低优化,更多调试信息,一般用-g ,低级代码用-cg |
-cg | 同上,经常同-keepc 一起用.这样,(gdb,lldb) 等可显示生成的C源码 |
-showcc | 打印用C的构建命令 |
-show-c-output | 打印编译时输出 |
-keepc | 不删生成的C源码 . |
为了最佳的调试你写的C
包装器,你可以v -keepc -cg -showcc yourprogram.v
,然后运行调试器.
用-o
来生成C
源码.只看生成的源码中的一个函数:-printfn main -o file.c
.
用V
调试:./v -g -o v cmd/v.
.调试测试:v -g -keepc prog_test.v
.
v help
列出v
的所有支持命令.如v help build/v help build-c
命令行调试:v -g 你好.v
,再用lldb 你好
.
条件编译
$
为编译时操作前缀.如$如
条件,类似C++的如 常式/D的静如
了:
//单分支支持多条件
$if ios || android {
println("移动设备!")
}
$if linux && x64 {
println("64位林操.")
}
//作为表达式用.
os := $if windows { "Windows" } $else { "UNIX" }
println("用$os")
// $异-$如分支
$if tinyc {
println("tinyc")
} $else $if clang {
println("clang")
} $else $if gcc {
println("gcc")
} $else {
println("不同编译器")
}
$if test {
println("测试")
}
// v -cg ...
$if debug {
println("调试")
}
// v -prod ...
$if prod {
println("生产环境")
}
// v -d option ...
$if option ? {
println("自定义选项")
}
如果想编译时执行,前面要加$
,目前支持检查操系/编译器/平台/编译选项
.
$if debug
是类似$if windows/$if x32
的特殊选项.自定义,需要$if option ? {}
,然后命令行中v -d option
.目前支持:
操系 | 编译器 | 平台 | 其他 |
---|---|---|---|
windows,linux,macos | gcc,tinyc | amd64,arm64 | 调试,生产,测试 |
mac,darwin,ios, | clang,mingw | x64,x32 | js,glibc,预分配 |
android,mach,dragonfly | msvc | 小头 | 无检查边界,独立 |
gnu,hpux,haiku,qnx | c++ | 大头 | - |
$embed_file
import os
fn main() {
embedded_file := $embed_file("v.png")
os.write_file("exported.png", embedded_file.to_string()) ?
}
可用$embed_file
来嵌入任意文件至exe
,相对/绝对
路径均可.不用-prod
时,不嵌入文件.
而在运行时调用f.data()
.使你外部修改程序,而不必重新编译.
用-prod
时,嵌入程序,虽然增大了,但自包含,更易分发,f.data()
不产生io
,但返回相同数据.
$tmpl
嵌入和解析模板
数据.
V
支持(超)文本模板
,可$tmpl("path/to/template.txt")
这样嵌入.
fn build() string {
name := "张三"
age := 25
numbers := [1, 2, 3]
return $tmpl("1.txt")
}
fn main() {
println(build())
}
//1.txt如下
name: @name
age: @age
numbers: @numbers
@for number in numbers
@number
@end
$env
.环境变量:
module main
fn main() {
compile_time_env := $env("ENV_VAR")
println(compile_time_env)
}//编译时从环境变量中取值.
$env("ENV_VAR")
可用在顶级#flag和#include
语句中.如#flag linux -I $env("JAVA_HOME")/include
.
环境相关文件
后缀 | 意思 |
---|---|
.js.v | 只编译成js |
.c.v | 编译为c |
.native.v | 本地 |
_nix.c.v | 联操系统 |
_${os}.c.v | 指定操系 |
_windows.c.v | 窗口 |
_default.c.v | 默认 |
//主.v
module main
fn main() { println(message) }
//main_default.c.v:
module main
const ( message = "你好 world" )
//main_linux.c.v:
module main
const ( message = "你好 linux" )
//main_windows.c.v:
module main
const ( message = "你好 windows" )
关键字
as asm assert atomic break const continue defer else embed enum false fn for go goto if import in interface is lock match module mut none or pub return rlock select shared sizeof static struct true type typeof union unsafe __offsetof
操作符
符号 | 意思 | 类型 |
---|---|---|
+ | 和 | 整,浮,串 |
- | 差 | 整,浮 |
* | 积 | 整,浮 |
/ | 商 | 整,浮 |
% | 余 | 整 |
~ | 按位非 | 整 |
& | 按位与 | 整 |
| | 按位或 | 整 |
^ | 按位异或 | 整 |
! | 逻辑非 | 极 |
&& | 逻辑与 | 极 |
|| | 逻辑或 | 极 |
!= | 逻辑异或 | 极 |
<< | 左移 | 整<<正 |
>> | 右移 | 整>>正 |
优先级 | 操作符 |
---|---|
5 | *,/,%,<<,>>,& |
4 | +,-,|,^ |
3 | ==,!=,<,<=,>,>= |
2 | && |
1 | || |
赋值操作符
+=,-=,*=,/=,%=,&=,|=,^=,>>=,<<=
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现