V语言04语句表达式

a := 10
b := 20
if a < b {
	println("$a < $b")
} else if a > b {
	println("$a > $b")
} else {
	println("$a == $b")
}

注意:没有括号,且{}是必须的.可用作表达式返回值.

num := 777
s := if num % 2 == 0 { "even" } else { "odd" }
println(s)
// "odd",真难受.一个`?:`不就行了

is及其否定!is来检查类型.

struct Abc {
	val string
}

struct Xyz {
	foo string
}

type Alphabet = Abc | Xyz

x := Alphabet(Abc{"test"}) //就是变量.
if x is Abc {
	// x自动转为Abc,可在此用
	println(x)
}
if x !is Abc {
	println("非Abc")
}

或用匹配.

match x {
	Abc {
		//x自动转为Abc
		println(x)
	}
	Xyz {
		//x自动转为Xyz
		println(x)
	}
}

也可以:

struct MyStruct {
	x int
}

struct MyStruct2 {
	y string
}

type MySumType = MyStruct | MyStruct2

struct Abc {
	bar MySumType
}//两个都可以

x := Abc{
	bar: MyStruct{123} //MyStruct自动转为MySumType
}
if x.bar is MyStruct {
	// x.bar自动转
	println(x.bar)
}
match x.bar {
	MyStruct {
		// x.bar自动转
		println(x.bar)
	}
	else {}
}

转换可能不安全,但有用.用mut标记表达式,表明程序员懂得起.

mut x := MySumType(MyStruct{123})
if mut x is MyStruct {
	//即使x可变,x转为MyStruct,无mut不行
	println(x)
}
//匹配也一样
match mut x {
	//即使x可变,x转为MyStruct,无mut不行
	MyStruct {
		println(x)
	}
}

in检查是否在数组/映射.!in表不在.

nums := [1, 2, 3]
println(1 in nums) // 真
println(4 !in nums) // 真
m := map{
	"one": 1
	"two": 2
}
println("one" in m) // 真
println("three" !in m) // 真

布尔表达式中更清晰/紧凑.

enum Token {
	plus
	minus
	div
	mult
}

struct Parser {
	token Token
}

parser := Parser{}
if parser.token == .plus || parser.token == .minus || parser.token == .div || parser.token == .mult {//太丑陋.优化成下面了,无数组
	// ...
}
if parser.token in [.plus, .minus, .div, .mult] {//这样.
	// ...
}//应该

V只有一个带多种形式的for循环关键字.
for/in.与数组/映射/区间一起用.

numbers := [1, 2, 3, 4, 5]
for num in numbers {
	println(num)
}
names := ["Sam", "Peter"]
for i, name in names {
	println("$i) $name")
	// 输出:0) Sam
	//      1) Peter
}
//上面为只读,下面可变.
mut numbers := [0, 1, 2]
for mut num in numbers {
	num++
}
println(numbers) // [1, 2, 3]

_则忽略掉了.映射版:

m := map{
	"one": 1
	"two": 2
}
for key, value in m {
	println("$key -> $value")
	// 输出: one -> 1
	//       two -> 2
}

键值用_来表示忽略.

m := map{
	"one": 1
	"two": 2
}
//迭代键
for key, _ in m {
	println(key)
	// Output: one
	//         two
}
//迭代值
for _, value in m {
	println(value)
	// Output: 1
	//         2
}
for i in 0 .. 5 {
	print(i)
}//迭代区间

低..高区间,为[)左闭右开.

mut sum := 0
mut i := 0
for i <= 100 {//相当于(当while)了.
	sum += i
	i++
}
println(sum) // "5050"

类似当/while,不满足条件则退出.必须无(){}.

mut num := 0
for {
	num += 2
	if num >= 10 {
		break
	}
}//类似(当1{})
println(num) // "10"

C风格,

for i := 0; i < 10; i += 2 {
	// 不打印6
	if i == 6 {
		continue
	}
	println(i)
}//这里(i)不必为`mut`,按定义,总是`可变`的

好,因为容易忘记更新记数器,从而死循环.
断/下控制流程,后可接标签.

outer: for i := 4; true; i++ {
	println(i)
	for {
		if i < 7 {
			continue outer
		} else {
			break outer
		}
	}
}

标签必须紧接外部循环.
匹配:

os := "windows"
print("V运行在")
match os {
	"darwin" { println("macOS.") }
	"linux" { println("Linux.") }
	else { println(os) }
}

匹配就是多个如异如异.找到分支运行相应块,找不到,运行块.

number := 2
s := match number {
	1 { "one" }
	2 { "two" }
	else { "many" }
}

匹配表达式,返回匹配分支的最后表达式.

enum Color {
	red
	blue
	green
}

fn is_red_or_blue(c Color) bool {
	return match c {
		.red,.blue{true}//逗号表示匹配多个值
		.green { false }
	}
}

也可匹配枚举变量,用.枚举项来简写,当分支填满了时,不能用.

c := `v`
typ := match c {
	`0`...`9` { "digit" }
	`A`...`Z` { "uppercase" }
	`a`...`z` { "lowercase" }
	else { "other" }
}//严重抄袭D,D这里为`..`.
println(typ)
// "lowercase"

这里区间,用...来表示左闭右闭都包含的意思.匹配中用..报编译错误.在for循环与if语句中不能用匹配表达式.
延时语句,

import os

fn read_log() {
	mut ok := false
	mut f := os.open("log.txt") or { panic(err.msg) }
	defer {
		f.close()
	}
	// ...
	if !ok {
		//在此执行延时.
		return
	}
	// ...
	//这里执行延时语句
}//类似`D`的`域(成功)`.

函数返回值,则在求值中语句后执行延时.

import os

enum State {
	normal
	write_log
	return_error
}

//写日志文件,并返回已写字节数
fn write_log(s State) ?int {
	mut f := os.create("log.txt") ?
	defer {
		f.close()
	}
	if s == .write_log {
		// `f.close()`在`f.write()`后执行
        //但在返回给`主`函数前执行
		return f.writeln("这是日志文件")
	}
    else if s == .return_error {
		//在错误()后,报告仍是打开
		return error("未写;打开文件: $f.is_opened")
	}
	//分支
	return 0
}

fn main() {
	n := write_log(.return_error) or {
		println("错误: $err")
		0
	}
	println("已写$n字节")
}
posted @   zjh6  阅读(16)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示