结构体
基本用法
struct Point {
x int
y int
}
mut p := Point{
x: 10
y: 20
}
println(p.x) // 通过点号访问字段
// 简化字面量语法
p = Point{10, 20}
assert p.x == 10
结构体字段可使用保留关键字:
struct Employee {
type string
name string
}
employee := Employee{
type: 'FTE'
name: 'John Doe'
}
println(employee.type)
堆结构体
结构体默认分配在栈上。使用 &
前缀可在堆上分配并获取引用:
p := &Point{10, 10}
println(p.x) // 引用语法相同
p
的类型是 &Point
(指向 Point 的引用)。引用行为类似 Go 指针和 C++ 引用。
可变性规则:
struct Foo {
mut:
x int
}
// 值拷贝可修改
mut a := Foo{1}
a.x = 2 // 允许
// 不可变实例的引用不可修改
fb := Foo{1}
mut b := &fb // 错误:`fb` 不可变
// 可变实例的引用可修改
mut fc := Foo{1}
mut c := &fc
c.x = 2 // 修改成功
println(fc) // 输出:Foo{x:2}
默认字段值
struct Foo {
n int // 默认 0
s string // 默认 ''
a []int // 默认 []
pos int = -1 // 自定义默认值
}
所有字段在创建时初始化为零值。可自定义默认值。
必填字段
使用 @[required]
标记字段为必须初始化:
struct Foo {
n int @[required]
}
// 缺少初始化会编译失败
_ = Foo{} // 错误:缺少字段 n
简化字面量语法
// 自动推断类型
points := [Point{10, 20}, Point{20, 30}]
// 函数参数可省略结构体名
fn new_point(p Point) {...}
new_point(x:10, y:20)
结构体更新语法
struct User {
name string
is_registered bool
}
fn register(u User) User {
return User{...u, is_registered:true} // 保留原字段
}
mut user := User{name:'abc'}
user = register(user)
println(user) // {name:'abc', is_registered:true}
尾随结构体参数
替代默认参数/命名参数:
@[params] // 允许完全省略参数
struct ButtonConfig {
text string
width int = 70 // 默认值
}
fn new_button(c ButtonConfig) &Button {...}
button := new_button(text:'Click', width:100) // 省略 height
需用 @[params]
标记结构体,否则至少需指定一个字段。
访问修饰符
共有五种访问级别:
struct Foo {
a int // 私有不可变 (默认)
mut: b int // 私有可变
c int // 同组可多字段
pub: d int // 公共只读
pub mut:e int // 仅父模块可修改
__global:f int // 全局可修改(不推荐)
}
匿名结构体
struct Book {
author struct { // 匿名内嵌
name string
age int
}
}
book := Book{author: struct {name:'Samantha', age:24}}
assert book.author.name == 'Samantha'
静态类型方法
struct User {}
fn User.new() User { // 类型名.方法名
return User{}
}
user := User.new() // 替代工厂函数
非构造函数,V 无类或构造函数概念。
[noinit]结构体
用 @[noinit]
禁止模块外初始化:
module sample
@[noinit]
pub struct Info { data string }
// 通过工厂函数创建
pub fn new_info(data string) !Info {...}
外部调用:
import sample
info := sample.new_info('data')! // 直接初始化会报错
方法
struct User { age int }
// 方法定义
fn (u User) can_register() bool {
return u.age > 16
}
println(User{age:10}.can_register()) // false
方法需与接收者类型同模块,接收者命名建议简短。
嵌入结构体
struct Size {
mut: width int, height int
}
fn (s Size) area() int { return s.width * s.height }
struct Button {
Size // 嵌入
title string
}
// 直接访问嵌入字段/方法
mut button := Button{title:'Click', height:2}
button.width = 3
assert button.area() == 6
// 显式访问嵌入结构体
assert button.Size.area() == 6
初始化方式:
button = Button{
Size: Size{width:3, height:2}
}
// 或单独赋值
button.Size = Size{width:4, height:5}
嵌入为混入(mixins)而非继承:
- 不能类型转换
- 字段名冲突时需显式指定(如
button.Size.area()
)