类型
基本类型
bool // 布尔值
string // 字符串
i8 i16 int i64 // 有符号整数 (i128 即将支持)
u8 u16 u32 u64 // 无符号整数 (u128 即将支持)
rune // Unicode 字符码
f32 f64 // 浮点数
isize, usize // 平台相关指针大小
voidptr // 主要用于 [C 交互](#v-and-c)
any // 类似 C 的 void* 和 Go 的 interface{}
注意: 与 C/Go 不同,V 的 int 固定为 32 位整数。
类型自动提升规则(当值域兼容时):
字面量默认类型:123 → int,4.56 → f64
类型转换示例:
u := u16(12)
v := 13 + u // v 为 u16 类型(无类型提升)
x := f32(45.6)
y := x + 3.14 // y 为 f32 类型
字符串(String)
UTF-8 编码,默认不可变:
s := 'hello 🌎'
assert s.len == 10 // 长度按字节计算
// 类型转换
bytes := s.bytes() // string → []u8
str := bytes.bytestr() // []u8 → string
// 索引与切片
name := 'Bob'
assert name[0] == u8(66) // 索引返回字节
assert name[1..3] == 'ob' // 切片返回字符串
// 转义序列
win_line := '\r\n' // 标准转义
hex_str := '\x61ardvark' // 十六进制
oct_str := '\141ardvark' // 八进制
star_str := '\u2605' // Unicode ★
禁止直接修改字符串:mut s := 'hello'; s[0] = 'H' 会触发错误。
字符处理技巧:
// 字节转字符串
'Netherlands'[0].ascii_str() // "N"
// 获取字符码序列
'hello 🌎'.runes() // 返回 7 个字符码(非 ASCII 字符按 1 个计算)
// 原始字符串(不处理转义)
raw_str := r'hello\nworld' // 输出 "hello\nworld"
// 字符串转整数
'0xc3'.int() == 195 // 支持所有进制
字符串插值
基础用法:
name := 'Bob'
println('Hello, ${name}!') // Hello, Bob!
格式化语法 ${var:[flags][width][.precision][type]}
:
x := 123.4567
println('[${x:.2}]') // [123.46] // 保留两位小数
println('[${x:10}]') // [ 123.457] // 右对齐
println('[${int(x):b}]')// [1111011] // 二进制
println('[${'a':3r}]') // [aaa] // 重复三次
字符串运算符
仅支持同类型操作:
mut s := 'hello '
s += 'world' // 正确拼接
// 'age=' + 12 // 错误!需转换或使用插值:
'age=${12}' // 推荐方式
字符码 (Rune)
表示 Unicode 字符:
rocket := `🚀`
assert rocket.bytes() == [0xf0, 0x9f, 0x9a, 0x80] // UTF-8 字节序列
assert rocket.str() == '🚀' // 转字符串
// 字符串与字符码互转
'👋'.runes() == [`👋`] // 字符串 → 字符码数组
数值类型
声明与转换:
a := 123 // int
b := 0x7B // 十六进制
c := 0b0111_1011 // 二进制(支持分隔符)
d := 1_000_000 // 等效 1000000
f := 1.0 // f64
f1 := f32(3.14) // 显式指定类型
sci := 42e1 // 科学计数法 (420)
数组
初始化与操作:
mut nums := [1, 2, 3]
nums << 4 // 追加元素 → [1,2,3,4]
nums << [5,6] // 追加数组 → [1,2,3,4,5,6]
println(nums[0]) // 索引访问 → 1
println(nums.len) // 长度 → 5
高级初始化:
// 预分配容量
mut arr := []int{cap: 1000}
for i in 0..1000 { arr << i } // 避免重复分配
// 带初始值的数组
arr2 := []int{len: 4, init: index} // [0,1,2,3]
多维数组:
// 二维数组
mut matrix := [][]int{len: 2, init: []int{len: 3}}
matrix[0][1] = 5 // [[0,5,0], [0,0,0]]
// 三维数组
mut cube := [][][]int{len: 2, init: [][]int{len: 3, init: []int{len: 2}}}
数组方法链式调用:
[1,2,3,4,5]
.filter(it % 2 == 0) // [2,4]
.map(it * 10) // [20,40]
数组切片
规则与技巧:
nums := [0,10,20,30,40]
slice1 := nums[1..4] // [10,20,30]
slice2 := nums[..3] // [0,10,20]
// 负索引切片
a := [0,1,2,3,4,5,6,7,8,9]
a#[-3..] // [7,8,9]
a#[..-3] // [0,1,2,3,4,5,6]
固定大小数组
栈上分配,高效但长度不可变:
mut fixed := [3]int{} // 固定长度数组
fixed[0] = 1
arr := fixed[..] // 转为普通数组(触发拷贝)
映射 (Map)
操作与特性:
mut m := map[string]int{}
m['one'] = 1
println(m['bad_key']) // 返回零值 → 0
println('one' in m) // 检查键是否存在 → true
// 初始化简写
numbers := {'one':1, 'two':2}
// 安全访问
val := m['key'] or { panic('键不存在') }
// 嵌套映射
mut users := map[string]map[string]int{}
users['Bob'] = {'age': 42}
映射更新语法:
base := {'a':1, 'b':2}
updated := {...base, 'b':3, 'c':4} // {'a':1, 'b':3, 'c':4}