vlang
  • 目录
    • V语言学习笔记
    • 目录
    • 安装
    • 开发工具
    • 快速总览
    • 模块
    • 基本类型
    • 变量
    • 常量
    • 枚举
    • 数组
    • 字典
    • 流程控制
    • 函数
    • 结构体
    • 访问控制
    • 方法
    • 注解
    • 接口
    • 泛型
    • 类型别名
    • 联合类型
    • 联合体
    • 错误处理
    • 运算符重载
    • 内置json支持
    • 内置sql支持
    • 并发
    • 内存管理
    • 代码测试
    • 文档生成
    • 编译时代码
    • 包管理器
    • 单个V文件
    • V shell script
    • 不安全代码
    • 集成C代码库
    • 集成汇编代码
    • 裸机环境
    • 生成wasm
    • GUI开发
    • web开发
    • 数据库开发
  • builtin
  • strings
  • arrays
  • maps
  • datatypes
  • strconv
  • os
  • runtime
  • time
  • math
  • json
  • encoding
  • compress
  • toml
  • flag
  • term
  • log
  • io
  • readline
  • reflection
  • net
  • net.http
  • eventbus
  • regex
  • crypto
  • rand
  • sync
  • x
  • db.pg
  • db.mysql
  • db.mssql
  • db.sqlite
  • orm
  • ui
  • sokol
  • gg
  • gx
  • fontstash
  • stbi
  • clipboard
  • V抽象语法树
  • V语言服务
  • V编译器源代码
  • 生成C代码
  • 生成js代码
  • 生成go代码
  • 生成native代码
  • 解释器直接运行
  • 附录1 关键字
  • 附录2 运算符
  • 附录3 编码风格
  • 附录4 V编译器命令行使用
  • 附录5 V调试及错误定位
  • 附录6 V和Go基本语法参照
  • 附录7 V和Zig基本语法参照
由 GitBook 提供支持
在本页
  • 声明和赋值
  • 类型推断
  • 显示指定类型
  • 判断变量类型
  • 默认不可变
  • 多变量赋值
  • 强制类型转换
  • 静态局部变量
  • 默认没有模块级/全局变量

这有帮助吗?

  1. 目录

变量

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

声明和赋值

V语言中只有唯一的一种变量声明和赋值方式 :=,并且声明和赋值是要同时的,这意味着变量总会有一个初始值。

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

类型推断

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

显示指定类型

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

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

这个显示指定类型的风格,跟其他语言确实不太一样,一般的风格都是:

let x int = 1
let x: int = 1
//或者
var x int = 1
var x: int =1

判断变量类型

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

x := 3
s := 'abc'
println(typeof(x)) // int
println(typeof(s)) // string

默认不可变

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

mut age := 20
println(age)
age = 21
println(age)

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

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

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

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

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

生产编译(v -prod):编译器会报错,停止编译。

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

fn main() {
	age = 21 //变量还未声明
}
fn main() {
	age := 21 //变量声明和赋值后,没有使用,开发编译,只会警告,生产编译,会报错
}
fn main() {
	a := 10
	if true {
		a := 20 //跟其他语言不一样,没有上级变量隐藏,在函数内部,同名的变量只能定义一个
	}
}

多变量赋值

fn main() {
	f1()
	f2()
	f3()
	f4()
}

fn f1() {
	a, b, c := 1, 3, 5 // 多变量声明并赋值
	println(a)
	println(b)
	println(c)
}

fn f2() {
	mut a := 1
	mut b := 2
	a, b = b, a // 交换
}

fn f3() {
	mut a := 11
	mut b := 22
	mut c := 33
	mut d := 44
	a, b, c, d = b, a++, d + 1, -c // 多变量赋值
	println(a) // 22
	println(b) // 11
	println(c) // 45
	println(d) // -33
}

fn f4() {
  mut x, y := 1, 3 //注意,只有x是可以变的,y不可变
	mut a, mut b, mut c := 1, 2, 3 //a,b,c都是可变的
	println(a)
	println(b)
	println(c)
}

条件赋值

d, e, f := if true {
		1, 'awesome', [13]
	} else {
		0, 'bad', [0]
	}

匹配赋值

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

强制类型转换

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

module main

fn main() {
	x := int(3)
	y := u8(x)
	println('y is $y')
	z := f32(x)
	println('z is $z')
	f := 1.2
	i := int(f)
	println(i) // 输出1,强制转换丧失精度
}

静态局部变量

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

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

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

  • 在-translated模式中使用

  • 在unsafe函数和代码块中使用

module main

fn f() int {
	mut x := 1 //普通的局部变量
	x++
	return x
}

//一定要在unsafe函数中
@[unsafe]
fn f_static() int {
	unsafe { //在unsafe代码块中定义
		mut static x := 1 //静态局部变量
		x++
		return x
	}
}

fn main() {
	println(f()) // 2
	println(f()) // 2
	println(f()) // 2
	unsafe { //调用的时候也要使用unsafe代码块
		println(f_static()) // 2
		println(f_static()) // 3
		println(f_static()) // 4
	}
}

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

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

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

v -enable-globals run main.v
module main

// 单个全局变量定义
__global g1 int

// 组定义全局变量,类似常量组的定义
__global (
	g2 u8 
	g3 u8 
)

fn main() {
	g1 = 1
	g2 = 2
	g3 = 3
	println(g1)
	println(g2)
	println(g3)
}

可以使用 [c_extern]注解,在生成的C代码中,给全局变量增加extern关键字。

module main

// 增加extern关键字
 @[c_extern]
__global g1 int

// 组定义全局变量,类似常量组的定义
 @[c_extern]
__global (
	g2 u8 
	g3 u8 
)

fn main() {
	g1 = 1
	g2 = 2
	g3 = 3
	println(g1)
	println(g2)
	println(g3)
}

生成的C代码:

extern int  g1; // global4
extern u8  g2; // global4
extern u8  g3; // global4
上一页基本类型下一页常量

最后更新于1年前

这有帮助吗?