运算符重载
为了保持语言的简单性,V只支持有限的运算符重载,支持最常用的四则运算符,比较运算符,分配运算符的重载。重载通过自定义复杂类型的运算符语义,让代码可读性更好。
四则运算符:+,-,*,/,%
比较运算符:>, <, !=, ==, <=, >=
分配运算符:+=,-=,*=,/=
比较运算符重载不用自己定义,编译器会基于小于和等于自动生成。
分配运算符重载不用自己定义,编译器会基于四则运算符自动生成。
为了提高安全性和可维护性,运算符重载有以下限制:
重载运算符的函数内部禁止调用其它函数。
重载运算符的函数不能修改它们的参数。
运算符两边的参数类型必须是同一类型。
四则运算符的返回值必须跟结构体类型一致,比较运算符必须返回bool类型。
目前支持对:字典,结构体,泛型结构体,类型别名,进行运算符重载。
###结构体运算符重载
module main
struct Vec {
x int
y int
}
//四则运算符
pub fn (a Vec) + (b Vec) Vec {
return Vec{a.x + b.x, a.y + b.y}
}
pub fn (a Vec) - (b Vec) Vec {
return Vec{a.x - b.x, a.y - b.y}
}
pub fn (a Vec) * (b Vec) Vec {
return Vec{a.x * b.x, a.y * b.y}
}
pub fn (a Vec) / (b Vec) Vec {
return Vec{a.x / b.x, a.y / b.y}
}
fn (a Vec) % (b Vec) Vec {
return Vec{a.x % b.x, a.y % b.y}
}
//比较运算符,只需要重载<和==,其他比较运算符不用自己定义,编译器会基于<和==自动生成
fn (a Vec) == (b Vec) bool {
return a.x == b.x && a.y == b.y
}
fn (a Vec) < (b Vec) bool {
return a.x < b.x && a.y < b.y
}
fn (a Vec) str() string {
return '{${a.x}, ${a.y}}'
}
fn main() {
mut a := Vec{8, 15}
b := Vec{4, 5}
//四则运算符
println(a + b) // {12,20}
println(a - b) // {4,10}
println(a * b) // {32,75}
println(a / b) // {2,3}
println(a % b) // {0,0}
//分配运算符,分配运算符不用自己定义,会基于四则运算符自动生成
a += b
println('a+=b is: ${a}')
a -= b
println('a-=b is: ${a}')
a *= b
println('a*=b is: ${a}')
a /= b
println('a/=b is: ${a}')
//比较运算符
println(a == b) // false
println(a != b) // true
println(a > b) // true
println(a >= b) // true
println(a < b) // false
println(a <= b) // false
}
泛型结构体运算符重载
module main
struct Matrix[T] {
row int
col int
mut:
data [][]T
}
fn from_array[T](arr [][]T) Matrix[T] {
return Matrix[T]{
row: arr.len
col: arr[0].len
data: arr.clone()
}
}
fn (m1 Matrix[T]) + (m2 Matrix[T]) Matrix[T] { //对泛型结构体进行运算符重载
if m1.row != m2.row || m1.col != m2.col {
panic('Addition can only be performed on matrix with same size')
}
mut res := m1
for i in 0 .. m2.row {
for j in 0 .. m2.col {
res.data[i][j] += m2.data[i][j]
}
}
return res
}
fn (m1 Matrix[T]) == (m2 Matrix[T]) bool {
return m1.row == m2.row && m1.col == m2.col && m1.data == m2.data
}
fn (m1 Matrix[T]) < (m2 Matrix[T]) bool {
return m1.row < m2.row && m1.col < m2.col
}
fn main() {
mut a1 := from_array([[1, 2, 3], [4, 5, 6]])
a2 := from_array([[7, 8, 9], [10, 11, 12]])
plus_ret := a1 + a2
println(plus_ret)
assert plus_ret.row == 2
assert plus_ret.col == 3
assert plus_ret.data == [[8, 10, 12], [14, 16, 18]]
a1 += a2
println(a1)
assert a1.row == 2
assert a1.col == 3
assert a1.data == [[15, 18, 21], [24, 27, 30]]
eq_ret := a1 == a2
println(eq_ret)
assert !eq_ret
ne_ret := a1 != a2
println(ne_ret)
assert ne_ret
lt_ret := a1 < a2
println(lt_ret)
assert !lt_ret
le_ret := a1 <= a2
println(le_ret)
assert le_ret
gt_ret := a1 > a2
println(gt_ret)
assert !gt_ret
ge_ret := a1 >= a2
println(ge_ret)
assert ge_ret
}
类型别名运算符重载
除了可以对结构体定义运算符重载,还可以对类型别名进行运算符重载。
module main
type Vector = []f64 //类型别名
[heap]
struct HeapArray {
mut:
data []f64
}
fn new_vector(x f64, y f64, z f64, w f64) &Vector {
a := HeapArray{
data: [x, y, z, w]
}
return &Vector(&a.data)
}
pub fn (a &Vector) + (b &Vector) &Vector { //对类型别名进行运算符重载
mut res := HeapArray{
data: []f64{len: a.len}
}
for i := 0; i < a.len; i++ {
res.data[i] = (*a)[i] + (*b)[i]
}
return &Vector(&res.data)
}
fn main() {
mut a := new_vector(12, 4.5, 6.7, 6)
b := new_vector(12, 4.5, 6.7, 6)
dump(a)
dump(b)
c := a + b
dump(c)
}
如果结构体定义了运算符重载,类型别名也可以直接使用。
module main
pub struct Vector {
vec []f64
}
pub fn (a Vector) + (b Vector) Vector {
size := a.vec.len
if size != b.vec.len {
panic('unequal sizes')
}
mut c := []f64{len: size}
for i in 0 .. size {
c[i] = a.vec[i] + b.vec[i]
}
return Vector{
vec: c
}
}
type Vec = Vector //结构体定义了运算符重载,类型别名也可以使用
fn main() {
a := Vec{
vec: [0.1, 0.2]
}
b := Vec{
vec: [0.3, 0.2]
}
c := a + b
println(c)
}
最后更新于