Go数组,切片

数组

package main

import (
	"fmt"
)

func main() {

	// 数组初始化方式
	var a [3]int
	fmt.Println(a) // 定义长度为3的int型数组, 元素全部为0

	var a2 = [3]int{1, 2, 4}
	fmt.Println(a2) // 定义长度为3的int型数组, 元素为 1, 2, 4

	var a3 = [...]int{1: 3, 2: 2}
	fmt.Println(a3); // 定义长度为3的int型数组, 元素为 0, 3, 2
	//注释1:3 表示在1的位置设置3,1位前没有数据补0

	var a4 = [...]int{1, 2, 4: 5, 6}
	fmt.Println(a4) // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6

	a5 := [...]int{1, 2, 4: 5, 6}
	fmt.Println(a5) // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6

	// 数组访问方式
	for i := 0; i < 3; i++ {
		fmt.Printf("%v ", a2[i])
	}

	fmt.Printf("\n")
	for i := range a4 {
		fmt.Printf("%v ", i)
	}

	fmt.Printf("\n")
	for i, v := range a4 {
		fmt.Printf("b[%d]: %d\n", i, v)
	}

	// 函数调用数组
	var ptr *[3]int;
	ptr = &a2;
	fmt.Printf("a 变量的地址是: %x\n", &ptr) //c000080020
	display(a2)
}

func display(data [3]int) {
	var ptr *[3]int;
	ptr = &data;
	fmt.Printf("data 变量的地址是: %x\n", &ptr) //c000080028
	fmt.Println(data)
	//一个数组变量即表示整个数组,它并不是隐式的指向第一个元素的指针(比如C语言的数组),而是一个完整的值
}

字符串 : 字符串的元素不可修改,是一个只读的字节数组

注:Go语言除了for range语法对UTF8字符串提供了特殊支持外,还对字符串和[]rune类型的相互转换提供了特殊的支持

底层结构
type StringHeader struct {
    Data uintptr
    Len  int
}

在这里插入图片描述

package main

import "fmt"

func main() {
	s := "hello, world"
	hello := s[:5]
	world := s[7:]

	s1 := "hello, world"[:5]
	s2 := "hello, world"[7:]
	fmt.Println(s, hello, world, s1, s2)

	fmt.Printf("%#v\n", []byte("Hello, 世界")) //[]byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c}
	fmt.Printf("%v\n", []byte("Hello, 世界"))  //[72 101 108 108 111 44 32 228 184 150 231 149 140]
	fmt.Printf("%v\n", ("Hello, 世界"))        //Hello, 世界
}

切片

底层结构
type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

在这里插入图片描述

package main

import "fmt"

func main() {
	var s1 []int // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
	fmt.Println(s1)

	var s2 = []int{}
	fmt.Println(s2) // 空切片, 和 nil 不相等, 一般用来表示一个空的集合

	var s3 = []int{1, 2, 3}
	fmt.Println(s3); // 有3个元素的切片, len和cap都为3

	var s4 = s3[:2]
	fmt.Println(s4) // 有2个元素的切片, len为2, cap为3

	var s5 = s3[0:2:cap(s3)]
	fmt.Println(s5) // 有2个元素的切片, len为2, cap为3

	var s6 = make([]int, 3)
	fmt.Println(s6) // 有3个元素的切片, len和cap都为3

	var s7 = make([]int, 2, 3)
	fmt.Println(s7) // 有2个元素的切片, len为2, cap为3

	// 遍历切片
	for i := range s3 {
		fmt.Printf("a[%d]: %d\n", i, s3[i])
	}
	for i, v := range s3 {
		fmt.Printf("b[%d]: %d\n", i, v)
	}
	for i := 0; i < len(s3); i++ {
		fmt.Printf("c[%d]: %d\n", i, s3[i])
	}

	var a = []int{}
	//添加切片数据
	a = append(a, 1)
	a = append(a, 2, 3)
	a = append(a, []int{4, 5}...)
	a = append([]int{-1, 0}, a...)
	fmt.Println(a)

	a = append(a[:2], append([]int{-2}, a[2:]...)...)
	fmt.Println(a)

	fmt.Println(copy(a[2:], a[1:]))
	a[1] = 9
	fmt.Println(a)
	//没有专门的内置函数用于扩展切片的容量,append本质是用于追加元素而不是扩展容量,扩展切片容量只是append的一个副作用

	//删除切片数据
	a = a[2:]
	a = a[:len(a)-2]
	fmt.Println(a)

	a = append(a[:1], a[2:]...)
	fmt.Println(a)

	a = a[:1+copy(a[1:], a[1+1:])]
	fmt.Println(a)
}
基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制问题,并提供完整的Matlab代码实现。文章结合数据驱动方法与Koopman算子理论,利用递归神经网络(RNN)对非线性系统进行建模与线性化处理,从而提升纳米级定位系统的精度与动态响应性能。该方法通过提取系统隐含动态特征,构建近似线性模型,便于后续模型预测控制(MPC)的设计与优化,适用于高精度自动化控制场景。文中还展示了相关实验验证与仿真结果,证明了该方法的有效性和先进性。; 适合人群:具备一定控制理论基础和Matlab编程能力,从事精密控制、智能制造、自动化或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于纳米级精密定位系统(如原子力显微镜、半导体制造设备)中的高性能控制设计;②为非线性系统建模与线性化提供一种结合深度学习与现代控制理论的新思路;③帮助读者掌握Koopman算子、RNN建模与模型预测控制的综合应用。; 阅读建议:建议读者结合提供的Matlab代码逐段理解算法实现流程,重点关注数据预处理、RNN结构设计、Koopman观测矩阵构建及MPC控制器集成等关键环节,并可通过更换实际系统数据进行迁移验证,深化对方法泛化能力的理解。
### 数组切片的基本概念 在 Go 语言中,**数组**是一种固定长度的数据结构,用于存储相同类型的元素。数组的长度在声明时就必须确定,并且不能更改。例如: ```go var arr [5]int ``` 上述代码声明了一个长度为 5 的整型数组数组适用于存储固定数量的数据,且在访问元素时具有高效的性能[^1]。 与数组不同,**切片**(slice)是 Go 语言中一种更灵活的数据结构。切片是对数组的抽象,它提供了动态扩展的能力,允许在运行时根据需要调整其长度。切片的底层实际上仍然依赖于数组,但它通过三个要素来管理数据:指向底层数组的指针(`ptr`)、当前切片的长度(`len`)和容量(`cap`)[^4]。 ```go slice := arr[1:4] // 从数组 arr 中创建一个切片,包含索引 1 到 3 的元素 ``` ### 切片的创建方式 切片可以通过多种方式创建: 1. **从数组创建切片**:如上例所示,使用数组切片操作可以创建一个新的切片,该切片共享底层数组的数据。 2. **使用 `make` 函数创建切片**:`make` 函数允许指定切片的长度和容量,适用于需要预分配空间的场景。 ```go slice := make([]int, 3, 5) // 创建一个长度为 3,容量为 5 的切片 ``` 3. **使用字面量创建切片**:直接通过字面量的方式创建切片Go 会自动推导出其长度。 ```go slice := []int{1, 2, 3} ``` ### 切片的操作 切片支持多种操作,包括: - **访问元素**:通过索引访问切片中的元素,索引范围从 0 到 `len(slice)-1`。 ```go fmt.Println(slice[0]) // 输出第一个元素 ``` - **修改元素**:可以直接通过索引修改切片中的元素。 ```go slice[0] = 10 // 将第一个元素修改为 10 ``` - **追加元素**:使用 `append` 函数可以向切片追加元素。如果切片的容量不足以容纳新元素,Go 会自动分配一个新的底层数组,并将原有数据复制过去。 ```go slice = append(slice, 4) // 向切片末尾添加元素 4 ``` - **切片的切割**:可以通过切片操作来获取子切片,类似于从数组创建切片的方式。 ```go subSlice := slice[1:3] // 获取索引 1 到 2 的子切片 ``` ### 切片的注意事项 1. **空切片与 `nil` 切片**:空切片是一个长度为 0 的切片,而 `nil` 切片表示切片未被初始化。两者在某些情况下表现不同,例如使用 `len` 和 `cap` 函数时。 ```go var nilSlice []int // nil 切片 emptySlice := []int{} // 空切片 ``` 2. **切片的比较**:切片不能直接进行比较操作,只能与 `nil` 进行比较。 ```go if slice == nil { // 判断切片是否为 nil } ``` 3. **切片的扩容策略**:当使用 `append` 函数向切片追加元素时,如果当前切片的容量不足以容纳新元素,Go 会自动扩容。扩容策略通常是将容量翻倍,直到满足需求。 4. **删除元素**:切片本身没有内置的删除操作,但可以通过切片操作和 `append` 函数实现删除元素的功能。例如,删除索引 `i` 处的元素: ```go slice = append(slice[:i], slice[i+1:]...) ``` ### 切片的底层原理 切片的底层是一个数组,它通过 `ptr`、`len` 和 `cap` 三个要素来管理数据。`ptr` 指向底层数组的起始地址,`len` 表示当前切片的长度,而 `cap` 表示从 `ptr` 开始到底层数组末尾的总容量。这种结构使得切片可以在不重新分配内存的情况下进行扩展和收缩,从而提高了性能[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值