年轻人的第一篇V语言笔记
V语言极限学习
我听说V语言看文档半小时就能完全掌握????以我的智商一小时掌握不了我就给各位科普一下广告法???
宇宙惯例hello world
// first v code
fn main(){
printIn("hello world")
}
- 不需要行结束符
- v函数使用
fn
声明,和其他语言一样,main函数是程序入口 - 注释规则和c一样
- 输出使用内置函数
printIn()
宇宙惯例2. 1+1
fn main(){
a := 1
b := 2
mut name := "v langue"
name = "v"
printIn(add(a,b))
}
fn add(a int,b int) int {
return a+b
}
- 变量名在类型名之前(反人类)
- 函数和变量都可以提前,也就是可以“先调用,再声明”
- 变量用
:=
声明并初始化,变量默认不允许修改,要修改必须加mut
- 修改变量用
=
- v没有全局变量,变量只能在函数中定义
- 定义的变量必须使用,不允许只定义,不使用,和go像
- 子代码块中不允许使用父代码块中已经定义的变量,如下面的代码会编译出错
fn main(){
a := 20
if true{
a := 30
}
}
基本数据类型
string
在V中,字符串是只读字节数组。 字符串数据使用UTF-8编码。
单引号和双引号都可用于表示字符串(TODO:尚不支持双引号)。 为保持一致性,vfmt将双引号转换为单引号,除非该字符串包含单引号字符。
字符串是不可变的。 这意味着子字符串函数非常有效:不执行复制,不需要额外的分配。
All operators in V must have values of the same type on both sides. This code will not compile if age is an int:
println('age = ’ + age)
We have to either convert age to a string:
println('age = ’ + age.str())
or use string interpolation (preferred):
println(‘age = $age’)翻译
V中的所有运算符必须在两边都具有相同类型的值。如果age是int: println(‘age = ’ + age’),这段代码将无法编译。我们必须将age转换为一个字符串:println('age = ’ + age.str())或使用字符串插值(preferred): println(‘age = ’ $age’)
数组
fn main(){
a := [1,2,3]
printIn(a)
}
- 数组类型由数组第一个元素决定
- 数组中元素类型必须相同
- 使用
<<
在数组末尾插入元素 - 使用
.len
返回数组长度 -
val in array
,如果数组array包含val,返回true
字典
mut m := map[string]int{} // Only maps with string keys are allowed for now
m['one'] = 1
println(m['one']) // ==> "1"
这个字典人家似乎还没有写好,emmmm,一堆TODO,你先写着,咱不急,看下一个
流程控制
if
a := 10
b := 20
if a < b {
println('$a < $b')
} else if a > b {
println('$a > $b')
} else {
println('$a == $b')
}
- 条件没有小括号
- 始终有大括号
- if语句可以作为一个表达式
num := 777
s := if num % 2 == 0 {
'even'
}
else {
'odd'
}
println(s) // ==> "odd"
in
作用:
- 检查数组中是否含有某个元素
- 布尔表达式,如:
if parser.token == .plus || parser.token == .minus || parser.token == .div || parser.token == .mult {
...
}
if parser.token in [.plus, .minus, .div, .mult] {
...
}
上下两个是等价的,使用下面的语法时,v不会创建数组
for
for比较牛逼,因为我看他文档写的比之前的都多…(狗头),知道为啥吗,应为v只有一种循环,就是for,哈哈哈哈
虽然只有一种循环,但人家for有好几种啊~~~
for in
fn main(){
list := ['a','b','c']
for value in list{
printIn(value)
}
}
value-in
如果需要数据的索引,可以用另一种方法
names := ['Sam', 'Peter']
for i, name in names {
println('$i) $name') // Output: 0) Sam
} // 1) Peter
第二种for(类似于while)
mut sum := 0
mut i := 0
for i <= 100 {
sum += i
i++
}
println(sum) // ==> "5050"
- 不写条件将导致死循环
第三种for(类似c)
for i := 0; i < 10; i++ {
println(i)
}
- 为啥这儿的i不用加mut而可以变化??别问,文档这么写的!!!
Here i doesn’t need to be declared with mut since it’s always going to be mutable by definition.
switch
os := 'windows'
print('V is running on ')
switch os {
case 'darwin':
println('macOS.')
case 'linux':
println('Linux.')
default:
println(os)
}
这里的switch和c里的差不多,只不过v中不需要在每个case后面加break
结构体
结构体???你可别告诉我你面向过程啊
struct Point {
x int
y int
}
p := Point{
x: 10
y: 20
}
println(p.x) // Struct fields are accessed using a dot
- 属性访问用.
- 结构是在堆栈上分配的。若要在堆上分配结构并获取指向它的指针,请使用&,如
pointer := &Point{10, 10} // 有三个或更少字段的结构体可使用这种替代写法
println(pointer.x) // 用指针访问值和其他一样,都用.
- 结构体嵌套,目前还不支持,不过快了
// 就直接复制了,他支持了再说(到时候我也不一定看)
V doesn't have subclassing, but it supports embedded structs:
// TODO: this will be implemented later in June
struct Button {
Widget
title string
}
button := new_button('Click me')
button.set_pos(x, y)
// Without embedding we'd have to do
button.widget.set_pos(x,y)
访问修饰符
默认的结构体是私有的,不可变的,可以使用访问修饰符pub 和 mut 修改,pub和mut有五种组合(不明白了吧,还有一种pub mut mut),先把文档复制过来再看是个什么妖魔
struct Foo {
a int // private immutable (default)
mut:
b int // private mutable
c int // (you can list multiple fields with the same access modifier)
pub:
d int // public immmutable (readonly)
pub mut:
e int // public, but mutable only in parent module
pub mut mut:
f int // public and mutable both inside and outside parent module
} // (not recommended to use, that's why it's so verbose)
访问修饰符 | 作用 |
---|---|
不写(默认) | 私有,不可变 |
mut | 私有,可变 |
pub | 公有,不可变 |
pub mut | 公有,仅在父模块可变 |
pub mut mut | 公有,父模块内部外部都可变 |
一脸懵逼是吧,哈哈哈,依老衲看来,这和c++中的public,private啥的一样,只不过他的变量(不能叫变量吧,先这样叫)默认是常量(const)你定义时需要加一个mut才能变成其他语言的“变量”,加一个pub这个变量就变成公有变量,从结构体外部可以访问了,加一个pub mut他就在结构体内外可以访问,而只能在结构体内部能改变,如字符串结构体中的len,外部可以访问他,但不能改变它,内部才能改变,最后pub mut mut 就是内外都可以访问,都可以修改。
Methods,方法
v没有class 吓死我了,辛亏有方法
一个方法就是一个函数,它带一个特殊的参数(接收器)
// 继续粘贴文档代码,CV工程师,年薪百万,啊啊啊啊啊啊啊啊
struct User {
age int
}
fn (u User) can_register() bool {
return u.age > 16
}
user := User{age: 10}
println(user.can_register()) // ==> "false"
user2 := User{age: 20}
println(user2.can_register()) // ==> "true"
- 这里的can_register就是一个方法,他的接收器是u,类型是User,官方说接收器名字最好用简短的,别用self,this啥的,一个字母最好(要不然没特色,开玩笑的)
Pure functions by default
英语捉急,无法翻译,大概就是默认的纯函数,应为V没有全局变量,加上变量默认不能改变,哪怕是传参时也一样,
后面开始赋值粘贴了
struct User {
mut:
is_registered bool
}
fn (u mut User) register() {
u.is_registered = true
}
mut user := User{}
println(user.is_registered) // ==> "false"
user.register()
println(user.is_registered) // ==> "true"
fn multiply_by_2(arr mut []int) {
for i := 0; i < arr.len; i++ {
arr[i] *= 2
}
}
mut nums := [1, 2, 3]
multiply_by_2(mut nums)
println(nums) // ==> "[2, 4, 6]"
- 注意,在调用此函数时,必须在nums之前添加mut。 这清楚地表明被调用的函数将修改该值。
- 最好返回值而不是修改参数。修改参数应该只在应用程序的性能关键部分执行,以减少分配和复制。
- 使用user.register()或user = register(user)代替register(mut user)。
- V可以很容易地返回对象的修改版本:
fn register(u User) User {
return { u | is_registered: true }
}
user = register(user)
常量const
const (
PI = 3.14
World = '世界'
)
println(PI)
println(World)
- 常量使用const声明。
- 它们只能在模块级别(函数之外)定义。
- 常量名称必须大写。这有助于将它们与变量区分开来。
- 常数永远不会改变。
- V常量比大多数语言更灵活。您可以分配更复杂的值
struct Color {
r int
g int
b int
}
fn (c Color) str() string { return '{$c.r, $c.g, $c.b}' }
fn rgb(r, g, b int) Color { return Color{r: r, g: g, b: b} }
const (
Numbers = [1, 2, 3]
Red = Color{r: 255, g: 0, b: 0}
Blue = rgb(0, 0, 255)
)
println(Numbers)
println(Red)
println(Blue)
- 不允许使用全局变量,因此这非常有用。
模块化
V是一种非常模块化的语言。鼓励创建可重用模块,而且非常简单。要创建一个新模块,请创建一个目录,其中包含模块的名称和.v文件
cd ~/code/modules
mkdir mymodule
vim mymodule/mymodule.v
// mymodule.v
module mymodule
// To export a function we have to use `pub`
pub fn say_hi() {
println('hello from mymodule!')
}
你可以在mymodule /中拥有尽可能多的.v文件。
使用v -lib~ / code / modules / mymodule构建它。
就是这样,您现在可以在代码中使用它
module main
import mymodule
fn main() {
mymodule.say_hi()
}
- 注意,每次调用外部函数时都必须指定模块。
- 模块名称应该简短,不超过10个字符。
- 不允许循环导入。
- 您可以在任何地方创建模块。
- 所有模块都被静态地编译成一个可执行文件。
看了两个小时了,还没看完,以我的智商,算是告别代码界了,再见各位,我自闭了
上一篇: V语言关键字解读