变量

V是静态类型语言,每一个变量都有对应类型

声明和赋值

V语言中只有唯一的一种变量声明和赋值方式 :=

并且声明和赋值是要同时的,这意味着变量总会有一个初始值

  1. a:=false
  2. b:='abc'
  3. c:=3 //默认推断为int
  4. f:=3.1 //默认推断为f64

类型推断

上述的代码并没有体现出变量的类型,是因为编译器会根据变量的值自动进行类型推断

显示指定类型

如果不希望由编译器自动类型推断,可以通过T(value)的格式明确变量类型,T是类型,value是变量值

  1. x:=i64(3) //x是i64类型,而不是默认推断的int
  2. y:=f32(3.0) //y是f32类型,而不是默认推断的f64

判断变量类型

通过使用typeof内置函数,可以判断变量类型

  1. x:=3
  2. s:='abc'
  3. println(typeof(x)) //int
  4. println(typeof(s)) //string

默认不可变

跟rust一样,变量默认不可变,要声明为可变,使用mut关键字

  1. mut age := 20
  2. println(age)
  3. age = 21
  4. println(age)

要注意区分:=和=的不同之处:

:=的含义是为变量声明并赋值

=的含义是为变量绑定一个新的值,也可以理解为修改变量值

变量声明后,如果没有被使用:

开发模式(v run),编译器只是会警告,但是仍然继续编译,方便开发调试,而不用去临时注释掉

生产编译模式(-prod),编译器会报错,停止编译

以下几种情况的代码,会编译不通过:

  1. fn main() {
  2. age = 21 //变量还未声明
  3. }
  1. fn main() {
  2. age := 21 //变量声明和赋值后,没有使用,非生产编译,只会警告,--prod生产编译时会不通过
  3. }
  1. fn main() {
  2. a := 10
  3. if true {
  4. a := 20 //跟其他语言不一样,没有上级变量隐藏,在函数内部,同名的变量只能定义一个
  5. }
  6. }

多变量赋值

  1. fn main() {
  2. f1()
  3. f2()
  4. f3()
  5. f4()
  6. }
  7. fn f1() {
  8. a, b, c := 1, 3, 5 // 多变量声明并赋值
  9. println(a)
  10. println(b)
  11. println(c)
  12. }
  13. fn f2() {
  14. mut a := 1
  15. mut b := 2
  16. a, b = b, a // 交换
  17. }
  18. fn f3() {
  19. mut a := 11
  20. mut b := 22
  21. mut c := 33
  22. mut d := 44
  23. a, b, c, d = b, a++, d + 1, -c // 多变量赋值
  24. println(a) // 22
  25. println(b) // 11
  26. println(c) // 45
  27. println(d) // -33
  28. }
  29. fn f4() {
  30. mut a, mut b, mut c := 1, 2, 3 //多变量+可变赋值
  31. println(a)
  32. println(b)
  33. println(c)
  34. }

条件赋值

  1. d, e, f := if true {
  2. 1, 'awesome', [13]
  3. } else {
  4. 0, 'bad', [0]
  5. }

匹配赋值

  1. a, b, c := match false {
  2. true { 1, 2, 3 }
  3. false { 4, 5, 6 }
  4. else { 7, 8, 9 }
  5. }

强制类型转换

可以通过T( ) 对类型进行显示声明,或者强制类型转换

  1. module main
  2. fn main() {
  3. x := int(3)
  4. y := byte(x)
  5. println('y is $y')
  6. z := f32(x)
  7. println('z is $z')
  8. f := 1.2
  9. i := int(f)
  10. println(i) // 输出1,强制转换丧失精度
  11. }

静态局部变量

跟C的静态局部变量一样,用关键字 static 声明,静态局部变量的值在函数调用结束之后不会消失,而仍然保留其原值.

一般来说,普通的V代码很少会用到静态局部变量,只有跟C集成的时候才会用到.

使用静态局部变量有以下2种方式:

  • 在-translated模式中使用
  • 在unsafe函数和代码块中使用
  1. module main
  2. fn f() int {
  3. mut x:= 1 //普通的局部变量
  4. x++
  5. return x
  6. }
  7. [unsafe] //一定要在unsafe函数中
  8. fn f_static() int {
  9. unsafe { //在unsafe代码块中定义
  10. mut static x:= 1 //静态局部变量
  11. x++
  12. return x
  13. }
  14. }
  15. fn main() {
  16. println(f()) //2
  17. println(f()) //2
  18. println(f()) //2
  19. unsafe { //调用的时候也要使用unsafe代码块
  20. println(f_static()) //2
  21. println(f_static()) //3
  22. println(f_static()) //4
  23. }
  24. }

默认没有模块级变量/全局变量

V语言中的变量只能在函数中定义,就是局部变量,默认没有模块级变量,没有全局变量.

默认情况下编译器是没有全局变量声明的,但是为了跟C代码集成,有时候需要定义全局变量,可以在调用编译器时,通过增加 -enable-globals选项来启用

  1. v -enable-globals run main.v
  1. module main
  2. // 单个全局变量定义
  3. __global g1 int
  4. // 组定义全局变量,类似常量组的定义
  5. __global (
  6. g2 byte
  7. g3 byte
  8. )
  9. fn main() {
  10. g1 = 1
  11. g2 = 2
  12. g3 = 3
  13. println(g1)
  14. println(g2)
  15. println(g3)
  16. }