欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

年轻人的第一篇V语言笔记

程序员文章站 2022-05-15 18:17:43
...

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

作用:

  1. 检查数组中是否含有某个元素
  2. 布尔表达式,如:
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语言