V语言02基础2

数字

a := 123

默认为.

a := 0x7B
b := 0b01111011
c := 0o173

2,8,16进制均可.始终为型.与形式无关.以_为数字分隔符.

num := 1_000_000 // 1000000
three := 0b0_11 // 0b11
float_num := 3_122.55 // 3122.55
hexa := 0xF_F // 255
oct := 0o17_3 // 0o173

不同类型,这样转:

a := i64(123)
b := byte(42)
c := i16(12345)
//上为整,下为浮
f := 1.0
f1 := f64(3.14)
f2 := f32(3.14)

默认浮为f64,就像整默认为一样.

数组

相同类型元素的集合.

mut nums := [1, 2, 3]
println(nums) // `[1, 2, 3]`
println(nums[0]) // `1`
println(nums[1]) // `2`
nums[1] = 5
println(nums) // `[1, 5, 3]`

数组属性:

属性意思
len长度,
cap容量,内存空间,默认自动,可手动优化
mut nums := [1, 2, 3]
println(nums.len) // "3"
println(nums.cap) // >="3"
nums = [] // 空数组
println(nums.len) // "0"

属性只读,用户不可改.
[1, 2, 3]类型为[]整.而["a", "b"][]串.
可在首元素显式指定类型如:[byte(16), 32, 64, 128].数组类型不同,编译不过:[1, "a"].
第2种初化语法:

mut a := []int{len: 10000, cap: 30000, init: 3}
//指定数组`属性`来初化.

上面创建100003,空间保留为30000个元素大小.参数大小,容量,初化可选,大小默认为0,初化默认为相应类型的默认值.默认数值为0,串为"".保证容量>=大小.

arr := []int{len: 5, init: -1}
// `arr == [-1, -1, -1, -1, -1]`, arr.cap == 5
// 声明空数组
users := []int{}

置容量,可提升性能,因为不必再分配.

mut numbers := []int{cap: 1000}
println(numbers.len) // 0
// 现在附加元素,不会分配
for i in 0 .. 1000 {
	numbers << i
}

for区间,而<<操作符(把C++的废物利用好).
数组元素类型可为:

类型示例
数字[]int,[]i64
[]string
符文[]rune
布尔[]bool
数组[][]int
[]MyStructName
通道[]chan f64
函数[]MyFunctionType []fn (int) bool
接口[]MyInterfaceName
和类型(C++的变量类型)[]MySumTypeName
泛型[]T
映射[]map[string]f64
枚举[]MyEnumType
别名[]MyAliasTypeName
线程[]thread int
引用[]&f64
共享[]shared MyStructType

示例,和类型来创建处理不同类型点/线数组.

struct Point {
	x int
	y int
}

struct Line {
	p1 Point
	p2 Point
}

type ObjectSumType = Line | Point
//这就是传说中的`和类型`,C++的变量类型.

mut object_list := []ObjectSumType{}
object_list << Point{1, 1}//点
object_list << Line{//线
	p1: Point{3, 3}//由点构成的线.
	p2: Point{4, 4}
}
dump(object_list)//[和(点),和(线(点,点))]

多维数组

mut a := [][]int{len: 2, init: []int{len: 3}}
a[0][1] = 2
println(a) // [[0, 2, 0], [0, 0, 0]]
//上为2维,下为3维
mut a := [][][]int{len: 2, init: [][]int{len: 3, init: []int{len: 2}}}
a[0][1][1] = 2
println(a) // [[[0, 0], [0, 2], [0, 0]], [[0, 0], [0, 0], [0, 0]]]

数组操作,主要是<<,类似C++压后.也可附加整个数组.

mut nums := [1, 2, 3]
nums << 4
println(nums) // "[1, 2, 3, 4]"
//附加数组
nums << [5, 6, 7]
println(nums) // "[1, 2, 3, 4, 5, 6, 7]"
mut names := ["John"]
names << "Peter"
names << "Sam"
// names << 10  //类型不同,编译不过

in表示是否在数组中.

names := ["John", "Peter", "Sam"]
println(names.len) // "3"
println("Alex" in names) // 假

可用println(arr)打印数组,也易这样s := arr.str()转为串.

nums := [1, 2, 3]
nums_copy := nums.clone()
//这样复制.

过滤映射用.filter()和.map(),

nums := [1, 2, 3, 4, 5, 6]
even := nums.filter(it % 2 == 0)
println(even) // [2, 4, 6]
// filter can accept anonymous functions
even_fn := nums.filter(fn (x int) bool {
	return x % 2 == 0
})
println(even_fn)
words := ["你好", "世界"]
upper := words.map(it.to_upper())
println(upper) // ["你好", "世界"]
//映射也可接受(λ函数)
upper_fn := words.map(fn (w string) string {
	return w.to_upper()
})
println(upper_fn) // ["你好", "世界"]

it过滤/映射内置变量,指代当前元素,it->迭代/它的意思.
.any()和.all()表示数组满足任一/所有.

ums := [1, 2, 3]
println(nums.any(it == 2)) //真
println(nums.all(it >= 2)) //假

数组内置方法,其实数组就是C++向量.

方法意思
b := a.repeat(n)重复(a,n)
a.insert(i, val)i处插入
a.insert(i, [3, 4, 5])i处插入多个值
a.prepend(val)0处插入,前插
a.prepend(arr)前插数组
a.trim(new_len)截断长度
a.clear()清理,不改容量==a.截断(0).
v := a.first()a[0]
v := a.last()a[$-1]
v := a.pop()取尾并弹
a.delete_last()弹尾
b := a.reverse()逆向
a.reverse_in_place()原位逆向
a.join(joiner)用合并器合并串数组

排序数组

mut numbers := [1, 3, 2]
numbers.sort() // 1, 2, 3
numbers.sort(a > b) // 3, 2, 1

a,b来描述自定义排序.

struct User {
	age  int
	name string
}
mut users := [User{21, "张三"}, User{20, "李四"}, User{25, "王五"}]
users.sort(a.age < b.age) //按年龄排序
users.sort(a.name > b.name) //按名排序

数组切片

先是索引,增加时切片复制新数组了,用..表示.要求右端>=左端.无右则为$,无左,则为0.

nums := [0, 10, 20, 30, 40]
println(nums[1..4]) // [10, 20, 30]
//这里[1..4]其实是[1,4)左闭右开要注意.
println(nums[..4]) // [0, 10, 20, 30]
println(nums[1..]) // [10, 20, 30, 40]

V中,切片也是先是引用,增加后实例.与d区别是分配策略.

array_1 := [3, 5, 4, 7, 6]
mut array_2 := [0, 1]
array_2 << array_1[..3]
println(array_2) // `[0, 1, 3, 5, 4]`

切片用最小容量创建,即cap == len.增加大小时,立即重新分配并移动位置,因而与父独立,也叫增长时复制.先是引用,切片增加元素复制了.不具备引用特点了.

mut a := [0, 1, 2, 3, 4, 5]
mut b := a[2..4]
b[0] = 7 // `b[0]`引用`a[2]`
println(a) // `[0, 1, 7, 3, 4, 5]`//变化了.
b << 9
// `b`重新分配,与a独立了.
println(a) // `[0, 1, 7, 3, 4, 5]`不变了.
println(b) // `[7, 3, 9]`

添加数组元素,可能/可能不会使其与子切片独立.要看容量.

mut a := []int{len: 5, cap: 6, init: 2}
mut b := a[1..4]
a << 3
//无分配.
b[2] = 13 // 修改了`a[3]`
a << 4
//分配a,与b独立了.
b[1] = 3 //与`a`无关了.
println(a) // `[2, 2, 2, 13, 2, 3, 4]`
println(b) // `[2, 3, 13]`

父/子新分配内存前,则是引用(非独立)关系.在分配内存后,就是独立关系了.

固定大小数组

长度固定,只能原位修改元素.效率更高,占用内存更少,数据在上,不想分配在堆上时,用作缓冲.
多数方法定义在普通数组(d的动态数组)上.可用切片转成普通数组:

mut fnums := [3]int{} //固定3
fnums[0] = 1
fnums[1] = 10
fnums[2] = 100
println(fnums) // => [1, 10, 100]
println(typeof(fnums).name) // => [3]int

fnums2 := [1, 10, 100]! //短初化符号,(注意:可能要改)

anums := fnums[0..fnums.len]
println(anums) // => [1, 10, 100]
println(typeof(anums).name) // => []int

固定数组的切片,会直接复制.所谓固定数组就是D的静态数组,就是C普通数组.

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