go语言的基本语法

学了go语言但是一直没整理。。。那怎么证明我学了?如果学了之后忘了怎么复习?遂诞生这几篇,当作Linux中间的小插曲

整理一下go语言的基本语法:

package mainimport ("bufio""fmt""os"
)

在使用对应函数或接口的时候,要通过import导入对应的包,就像C语言中的头文件一样

变量声明及赋值:

1.正经的声明赋值使用关键字var:

var 变量名,数据类型
变量名=赋值

两行分别实现声明和赋值,也可以这样:

var 变量名 数据类型 =赋值

还可以批量声明赋值:

var (变量名1 变量类型1变量名2 变量类型2	
)

2.类型推断,不写明什么类型,后面编译的时候go会自己猜

var 变量名=赋值

3.简短声明,冒号左边至少有一个为赋值的新变量

sum :=100

定义全局变量不能简短声明,在go里面变量定义了就要用,不然会报错

go是静态语言(得显式的说明变量类型)和强类型语言(不会根据运算的语境切换数据的类型)

所以我们使用的时候如果不是对应类型的数据做运算的时候需要强制转换,定义、赋值、运算要保持一致:

内建变量类型
  1. bool、string
  2. (u)int、(u)int8、(u)int16、(u)int32、(u)int64、uintptr,u开头为无符号整型,范围没有负数部分
  3. byte、rune
  4. float32、float64、complex64、complex128

运算符:

转化为二进制,按位操作
       按位&:对应位置都为1才为1,有一个0就为0
       按位|:对应位置都为0才为0,有一个1就为1
       异或^:
                   1.a^b按位运算,相同为1,不同为0
                   2.^a按位取反
                   1->0,0->1
go语言特有:位清空&^
       a&^b对于b上的数值,如果为0,则取a对应位上的数值
       如果为1,则结果位就取0

">>"和"<<":

条件判断:

if做条件判断,可以在{}前声明变量,这个变量只作用于该if

	if res := 9; res > 0 { //if外面访问不了if里面的res,只作用于当前的iffmt.Println("res>0")}

switch也可以这么用:

func main() {switch num := 16; num {case 2:fmt.Println("2进制")case 8:fmt.Println("8进制")case 10:fmt.Println("10进制")case 16:fmt.Println("16进制")default:fmt.Println("内容不正确")}fmt.Println("程序结束")
}

default放哪里都行,只有当case一个都执行不了的时候,才能这么用

func main() {month := 5switch month {case 1, 3, 5, 7, 8, 10, 12:fmt.Println("31天")case 2:fmt.Println("28或29天")default:fmt.Println("30天")}fmt.Println("程序结束")
}

case条件支持多个值,每个值使用逗号分开

但是一般情况只会执行一个case,如果需要继续执行下面的分支,需要fallthrough:

fallthrough,满足条件后向下穿透,无条件执行下一个case的语句,放在case里面的最后一行
func main() {switch num := 1; num {case 1:fmt.Println("1")fallthroughcase 2:fmt.Println("2")case 3:fmt.Println("3")fallthroughcase 4:fmt.Println("4")default:fmt.Println("不是1,2,3,4")}fmt.Println("程序结束")
}

for的写法:

标准写法for 表达式1;表达式2;表达式3{}
其他写法:1.省略表达式1和3for (;)表达式2(;)(while)分号可不写2.省略所有表达式for(}相当于(while(1))死循环

遍历数组:

arr1 := [5]int{1, 2, 3, 4, 5}for index, value := range arr1 {fmt.Printf("下标是%d,数值是%d", index, value)}

数组、切片和映射

数组的数据类型为值类型,声明:

[长度]类型

值类型:array,int,float,string都是值类型
数组可以值传递,可值传递的数据类型为存储数值本身
传递的数值为备份(副本)

数组打印:

	arr1 := [5]int{1, 2, 3, 4, 5}for index, value := range arr1 {fmt.Printf("下标是%d,数值是%d", index, value)}

引用类型:传递地址,如slice(切片),map(映射)

silce声明:

var 名字 []

像vector,动态数组, 左闭右开

	array := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}   //设定初始数组ss1 := array[1:9]                                 //1-9,len:8,cap:9ss2 := array[:4]                                  //0-4,len:4,10fmt.Printf("%p,%d,%d\n", ss1, len(ss1), cap(ss1)) //检查容量fmt.Printf("%p,%d,%d\n", ss2, len(ss2), cap(ss2))

ss1和ss2是依托于array产生的切片,array是切片的底层数组

更改数组内容直接:

	array[4] = 100

更改切片内容同时也会更改底层数组的内容

ss2 = append(ss2, 50, 50, 50, 50) //ss2的后面改变,底层数组也被改变fmt.Println(ss2)fmt.Println(array) //底层数组也被更改

除了这种明着写的切片的底层数组,用make创建切片也会有自己的底层数组

哪怕长度和容量为0,也有底层数组

切片是引用类型,数组是值类型,所以我们直接打印一个切片的地址是指向他的底层数组的地址,对它再取地址,才是切片的地址

make函数:

make函数可以创建引用类型的数据,除了slice还有别的

使用格式:

    make(type,len,cap)类型,长度,容量

切片一旦扩容,指向一个新的数组地址,容量成倍增长,最大容量为1024

创建map:

var map3 = map[string]int{"GO": 98, "Python": 79, "Html": 93}

map:映射,键值对的集合,引用类型
存储特点:存储的是无序的键值对
       键不能重复,与value值一一对应,否则新的会覆盖旧的

每次创建一个map要:

1.map创建

2.判断map是否为空(map为空不能用,所以很重要)

3.存键值对到map中

4.获取数据

每种数据类型未赋值的初始值:
int:0
float:0.0->0
string:""
array:[00000]

slice:nil(空,但是因为有底层数组,所以未赋值也可直接使用
map:nil(空,但是不可以直接使用

把map比喻为盘子上放着饺子,那么:

var map1 map[int]string                                       //[key的类型]值的类型,没有盘子没有饺子var map2 = make(map[int]string)                               //有盘子没有饺子var map3 = map[string]int{"GO": 98, "Python": 79, "Html": 93} //有盘子,也装了饺子
//map1[1] = "hello"会报错

打印他们三个的结果:

//流程大概是这样:
var map1 map[int]string //定义mapif map1 == nil {//检查是否为空map1 = make(map[int]string)fmt.Println(map1 == nil)}map1[3] = "xixixi"//输入数据
map1[4] = ""fmt.Println(map1[3])//获取数据
fmt.Println(map1[2]) 

我们在上面的代码中打印了map1[2],但是我们没输这个键值对,会打印什么?

当然是打印“空”了

我们可以用ok-idiom(惯用法)来测试自己的键值对是否存在:

v4, ok := map1[4]if ok == true {fmt.Println("v4==", v4)}

打印出来也是空格

删除数据,函数delete

delete(map1, 4)
fmt.Println(map1)

删除后的结果:

遍历map:

map4 := make(map[int]string)map4[1] = "今天是5.27号"map4[2] = "我的自行车被学校拖走了"map4[3] = "我的雪顶咖啡化完了"map4[4] = "风是透明的河流"map4[5] = "水是流动的山川"for k, v := range map4 {fmt.Println(k, v) //map为无序存储,所以每次打印顺序不一样}

如何有序打印:

如果你的键值对中的k是有序的,可以按这个顺序打印:

for i := 1; i <= len(map4); i++ {fmt.Println(i, "-->", map4[i])} //如果k没有顺序就无法这样打印

可以利用map和silce的结合:

1.获取所有的key,->切片/数组存储
2.进行排序
3.遍历key,->map[key]

key := make([]int, 0, len(map4))fmt.Println(key)for k := range map4 {key = append(key, k)}fmt.Println(key) //每次顺序都不一样//排序sort.Ints(key)fmt.Println(key)for _, keys := range key {fmt.Println(keys, map4[keys])}

如果你有很多个map,可以用数组/切片来把这些map串起来,比如1对应的就是k值和k值映射的值,2对应自己的k值......以此类推

//map和slice结合使用,创建map->存入信息到map里->把map存入到slice里->遍历输出map5 := make(map[string]string)map5["name"] = "艾美莉卡"map5["age"] = "244"map6 := make(map[string]string)map6["name"] = "西安邮电大学"map6["age"] = "74"map7 := make(map[string]string)map7["name"] = "荷叶饭"map7["age"] = "18"str := make([]map[string]string, 0, 3)str = append(str, map5)str = append(str, map6)str = append(str, map7)for i, v := range str {fmt.Printf("第%d个人的姓名为%s\n", i+1, v["name"])fmt.Printf("年龄为%s\n", v["age"])fmt.Println()}

silen里套map,map里也可以套map:

map8 := make(map[string]map[string]string) //k为string,v为map[string][string]m1 := make(map[string]string)m1["name"] = "Go"m1["age"] = "15"map8["message"] = m1fmt.Println(map8)

 string:

定义字符串:

s1 := "hello world"
s2 := "hello 狗屎"

字符串长度:

fmt.Println(len(s1), len(s2))

获取某个字符:

    fmt.Println(s1[0])fmt.Printf("%c\n", s1[0])

字符串遍历:

1.

for i := 0; i < len(s2); i++ {fmt.Printf("%c\n", s2[i])} //后面乱码是因为中文是三个字节

2.

	for i, v := range s2 {fmt.Printf("%d %c\n", i, v) //没有乱码但是下标顺序不连续}

字符串其实就是一个byte的切片:

slice1 := []byte{65, 66, 67, 68, 69}
s3 := string(slice1) //根据一个字节切片,构建字符串
fmt.Println(s3)

反过来根据字符串构造byte数组:

s4:="abcde"
slice2:=[]byte(s4)
fmt.Println(slice2) //打印的是数值

字符串不能随意修改:

//s3[2]="ww",报错,字符串不可修改

字符串相关的函数:

string.Contains、string.ContainsAny、string.Count

	str := "世界是一个大妓院aaa"fmt.Println(strings.Contains(str, "妓院"))       //如果含有则truefmt.Println(strings.ContainsAny(str, "妓院abc")) //含有一部分则truefmt.Println(strings.ContainsAny(str, "狗屎"))    //false,包含其一即为true,都不包含则falsefmt.Println(strings.Count(str, "a"))           //统计a在str出现的次数,3

string.HasPrefix(以某个字符开头)、string.HasSuffix(以某个字符结尾)

str1 := "你的肛门比较松弛"if strings.HasPrefix(str1, "你") { //如果str1是以“你”开头fmt.Println("没错,", str1)} else {fmt.Println("不,他的肛门比较松弛")}if strings.HasSuffix(str1, "松弛") { //若以“松弛”为结尾fmt.Println(str1)}

string.Index(第一次出现某个字符)、LastIndex(最后出现某个字符)、IndexAny(出现某个字符串中的一个字符):

没有返回-1

	str := "世界是一个大妓院aaa"    fmt.Println(strings.Index(str, "a"))      //第一次出现"a"的下标,24fmt.Println(strings.LastIndex(str, "a"))  //最后一次出现“a"的下标,26fmt.Println(strings.Index(str, "b"))      //没有的话返回-1,-1fmt.Println(strings.IndexAny(str, "abc")) //出现”abc”任意一个排在前面的字符字符则返回下标,24

Join(将字符串数组以某个字符的形式连接起来):

str2 := []string{"abc", "def", "ghi", "jkl"}fmt.Println(strings.Join(str2, "+")) //拼接一个字符串数组中的字符

Split(分散字符串)Repeat(复制某个字符串几次)Replace(把字符串中的某个字符替换为目标字符串,替换n次,如果要全部替换则n置为负数)

    str3 := "原神,是一款由\"米哈游\"前面忘了,后面忘了"fmt.Println(strings.Split(str3, ","))            //从逗号处断开fmt.Println(strings.Repeat(str1, 5))             //自己拼接自己拼接了5次fmt.Println(strings.Replace(str, "世界", "肛门", 1)) //把str中的“世界”替换为“肛门”,替换一次//如果要全部替换则n取负数fmt.Println(strings.Replace(str, "a", "去死", -1))

ToLwer(大写变小写)ToUpper(小写换大写)

    str4 := "abcdefg"str5 := "ABCDEFG"fmt.Println(strings.ToLower(str5)) //大写字母全变成小写,ABCDEFG->abcdefgfmt.Println(strings.ToUpper(str4)) //小写字母全变成大写,abcdefg->ABCDEFG

截取字符串:

其他语言:substring(start,end)截取子串
go没有substring,但是我们的字符串本质上是个byte切片,我们可以从切片截取(左闭右开):

str := "世界是一个大妓院aaa"
fmt.Println(str[0:6]) //截取str的前六个字节,“世界”

strconv包的使用:

按住ctrl可以查看我们函数的源代码:

strconv.ParseBool将字符串转换为布尔值(bool)

strconv.ParseBool支持以下几种字符串输入,并且不区分大小写:

"1", "t", "T", "true", "TRUE", "True":会被解析为 true

"0", "f", "F", "false", "FALSE", "False":会被解析为 false

sss1 := "true"b1, err := strconv.ParseBool(sss1)if err == nil {fmt.Println(err)}fmt.Printf("%T,%t\n", b1, b1) //bool,true

strconv.ParseInt,将字符串转为int(不同进制)

    sss2 := "100"b2, err := strconv.ParseInt(sss2, 10, 64) //(字符串,进制,最大位数)if err == nil {fmt.Println(err)}fmt.Printf("%T,%d\n", b2, b2) //int64,100

itoa:字符串->int(10进制)

itoa:int->字符串

    //itoa(),atoi()i3, err := strconv.Atoi("-42") //字符串转为intfmt.Printf("%T,%d\n", i3, i3)  //int,-42i4 := strconv.Itoa(42)fmt.Printf("%T,%s\n", i4, i4) //string,42

函数和指针:

首先go语言支持多个返回值,一个函数可以返回多个值:

//函数
func rectang(len, wid float64) (float64, float64) {perimeter := 2 * (len + wid)area := len * widreturn perimeter, area
}
//主函数部分res1, res2 := rectang(5, 3)fmt.Println(res1, res2)

执行结果

如果你不像要其中一个返回值,也可以拿下划线代替

但是只要你定义了返回值,你就必须得返回

如果你的函数有返回值,并且包含了if分支,那么每个分支下都要有一个return语句来返回值(return来返回整个函数,break来中断这个分支)

defer(延迟)函数:使对应的语句暂停,放到最后执行

func fun1(a int) {fmt.Println(a)
}fun1(1111111)defer fun1(2222222)fun1(3333333)defer fun1(4444444)

不加defer应为
1111111
2222222
3333333
4444444

加了之后为
1111111
3333333
4444444
2222222

    因为defer置后了两个函数的调用,采用栈的结构打印
    先被defer的语句后执行,后被defer的语句先执行(后进先出)
defer函数:在return之前,所有的defer函数会执行完毕

当执行外围函数中的return语句时,只有其中所有的延迟函数都执行完毕后
外围函数才会真正返回。
当外围函数中的代码引发运行恐慌时,只有其中所有的延迟函数都执行完毕后,该运行时恐慌才会真正被扩展至调用函数;外围函数的恐慌不会影响内部的defer,得里面的defer执行完了,这个执行恐慌才会向调用处显现

函数的本质:

	fmt.Printf("%T\n", fun1) //func(int)fmt.Println(fun1)        //0xe4b3c0,函数名对应的函数体地址

	c := fun1                //c被赋值为赋值为fun1的地址fmt.Println(c)           //0x8cb400,所以“c"可以被当作函数调用c(6)fmt.Println(c) //6

匿名函数:

匿名函数:没有名字,直接在匿名函数后面加上“()"代表调用
     定义一个匿名函数后匿名函数直接被调用,一般只能调用一次
    也可以把这个匿名函数赋值给一个变量,这样就可以多次调用
go语言支持函数式编程:
1.将匿名函数作为另一个函数的参数,回调参数
2.将匿名函数作为另一个函数的返回值,可以形成闭包结构

匿名函数实例:

func() {fmt.Println("我是一个匿名函数")
}() //直接在匿名函数后面加上“()"代表调用

即使写一个新的一模一样结构的函数,也不是同一个函数,会开辟新的一块内存

把匿名函数赋值给变量b

b := func() {fmt.Println("我也是一个匿名函数")
}
b() //执行b

匿名函数也可以传递:

ans2 := func(a, b int) int {return a + b} //将匿名函数的地址给ans2fmt.Println(ans2) //0x2cb7a0

高阶函数:

go语言函数为一种数据类型,支持高阶函数:函数把另一个函数作为参数
fun1(),fun2()
将fun1函数作为了fun2()这个函数的参数
fun2:高阶函数
fun1:回调函数

函数是一种数据类型,是什么类型主要取决于参数列表和返回值列表的类型:

// 函数的类型:func(参数列表的类型)(返回值列表的类型)func add(a, b int) int {return a + b
}
func oper(a, b int, fun func(int, int) int) int {//把一个fun类型的func (int,int)参数fmt.Println(a, b, fun)res := fun(a, b)return res
}
    //打印函数类型fmt.Printf("%T\n", add)  //func(int, int) intfmt.Printf("%T\n", oper) //func(int, int, func(int, int) int) int

我们调用一下oper这个高阶函数:

    ans11 := add(12, 4)fmt.Println(ans11) //16ans22 := oper(10, 9, add)fmt.Println(ans22) //10 9 0x28b800,fun(10,9)==19

相当于在oper里调用执行了add

来聊聊我们刚才提到的闭包:

闭包(closure):
       一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量(外层函数中的参数,或者外层函数中直接定义的变量),
    并且该外层函数的返回值就是该内层函数,这个内层函数和外层函数的局部变量,统称为闭包结构

          闭包导致的变量逃逸:
          当外层函数的局部变量被内层函数使用时,外层函数的返回值为该内层函数,且该内层函数还会用到该局部变量
                则外层函数的局部变量不被销毁

闭包的结构:

  • 函数本身:闭包是一种函数,可以被调用和执行。
  • 函数的自由变量:这些是在函数定义时,函数外部的变量,但在函数内部被引用。这些变量没有在函数内部定义,称为“自由变量”。
  • 捕获的环境:闭包可以记住它定义时的上下文环境,也就是说即使函数的执行环境已经离开了当前作用域,闭包依然可以访问并使用这些自由变量。
eg:
func increment() func() int { //外层函数i := 0 //1.定义了一个局部变量//2.定义了一个匿名函数fun1 := func() int { //内层函数i++return i}return fun1 //3.返回该匿名函数}

来调用一下这个闭包:

ans111 := increment() //res111:=fun=内部的匿名函数v1 := ans111()fmt.Println(v1) //1v2 := ans111()fmt.Println(v2) //2,第二次调用i不会被销毁

按理来说你第一次调用这个ans111的时候,打印的v1=1很正常,因为你的i在闭包里设置的变量就是1

但是你第二次调用时,按理来说应该还是1啊?怎么就是2了?

局部变量的生命周期会发生变化,正常的局部变量会随着函数的调用创建,函数的结束销毁
但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁,因为内层函数还要继续使用

也就是说别的函数之所以销毁是因为没人用里面的变量了,才销毁;而闭包结构因为里面的内层函数还用,所以就没有销毁。再次调用会有一个新的i,但是这个新的i继承上次的值,也就是1
(每新调用一次外层函数,就会有一个新的i与之对应,但旧的仍继承)

指针

指针储存的是另一个变量的地址:

a := 10fmt.Println(a)var p *intp = &a                             //p等于a的地址,*p等于p的指的地址的值fmt.Println(*p)                    //10fmt.Println(p)                     //0xc00000a0c8fmt.Printf("%T,%p,%p\n", p, p, &p) //*int,0xc00000a0c8,0xc000058030,p的类型,p指的地址,p自己的地址

这是指针的指针:

	var p1 **intp1 = &p          //p1是p的指针,存的是fmt.Println(*p1) //0xc00000a0c8fmt.Println(p1)  //0xc000058030

数组指针:指向一个数组的指针
指针数组:首先是一个数组,存储的类型是指针

数组指针:

    //1.创建普通数组arr1 := [4]int{1, 2, 3, 4}fmt.Println(arr1)//2.创建数组指针var p2 *[4]intp2 = &arr1fmt.Println(p2)                       //&[1 2 3 4]fmt.Printf("%T,%p,%p\n", p2, p2, &p2) //*[4]int,0xc000014200,0xc000058038,类型,数组arr1的地址,p2指针自己的地址//3.根据数组指针,操作数组(*p2)[1] = 100  //&[1 100 3 4]p2[0] = 200     //简化写法fmt.Println(p2) //&[200,2,3,4]

指针数组:

    b := 1c := 2d := 3e := 4arr2 := [4]int{b, c, d, e}arr3 := [4]*int{&b, &c, &d, &e}fmt.Println(arr2) //[1 2 3 4]fmt.Println(arr3) //[0xc00000a148 0xc00000a150 0xc00000a158 0xc00000a160]*arr3[0] = 100fmt.Println(b) //100

这么写肯定是错的:

fmt.Println(*(arr3))不能这么写,不能直接对指针数组解引用,应该对数组的每个元素进行解引用

只能遍历指针数组中的每个指针然后对指针解引用:

for i, v := range arr3 {fmt.Printf("Element %d: %d\n", i, *v)}

函数指针:

函数指针:指向函数地址的指针
go语言中函数为值类型,可以代替传统意义上的“函数指针”,因为函数变量已经可以直接表示指向函数的操作。(虽然go也可以用指针做中间人来使一个函数等于另一个函数但往往没必要)

func fun5() {fmt.Println("fun1()")
}//函数部分var f func()f = fun5 //函数是一个指针,f()      //f()==fun1(),也可以写成*f(),但go中可以舍去*
func fun3() *[4]int {arr := [4]int{5, 6, 7, 8}return &arr
}
func fun2() [4]int {arr := [4]int{1, 2, 3, 4}return arr
}
arr4 := fun2()fmt.Printf("arr4:类型%T,地址%p,数值%v\n", arr4, &arr4, arr4) //arr4:类型[4]int,地址0xc0000142a0,数值[1 2 3 4]//函数内的arr被销毁arr5 := fun3()fmt.Printf("arr5:类型%T,地址%p,存的地址:%p,数值%v\n", arr5, &arr5, arr5, arr5) //arr5:类型*[4]int,地址0xc000058040,存的地址:0xc000014300,数值&[5 6 7 8]//函数内的arr没有被销毁,因为arr5==fun3()返回值的地址

指针作为参数:

参数传递:值传递,引用传递

    func fun6(num int) { //值传递num = 100fmt.Println("num在函数中被修改")
}
func fun7(p1 *int) { //引用传递fmt.Println("fun7()函数中,p1:", *p1) //fun7()函数中,p1: 10*p1 = 200                         //p1在函数结束后会被销毁,但是因为p1指的地址为输入进来的实参的值,所以被传入的实参(g)的值被指针改变,销毁指针p1的内存地址,不销毁实参的地址fmt.Println("fun7()函数中,p1:", *p1) //fun7()函数中,p1: 200
}
func funexe1(p1 *[4]int) {fmt.Println("函数中的p1", p1)  //&[1 2 3 4]fmt.Println("函数中的p1", *p1) //[1 2 3 4]p1[0] = 200
}
func funexe2(arr [4]int) {fmt.Println("函数中的arr", &arr) //&[200 2 3 4]fmt.Println("函数中的arr", arr)  //[200 2 3 4]arr[1] = 99
}
//上面是函数部分g := 10fmt.Println("fun6()函数调用前,g:", g) //fun6()函数调用前,g: 10fun6(g)fmt.Println("fun6()函数调用后g:", g) //fun6()函数调用后g: 10,为什么调用后还是10?因为他是值类型,在函数运行时变成100,函数结束后100就被销毁了fun7(&g)fmt.Println("fun7()函数调用后,g:", g) //fun7()函数调用后,g: 200arrexe := [4]int{1, 2, 3, 4}funexe1(&arrexe)//传的是地址fmt.Println(arrexe)//200,2,3,4funexe2(arr1)//函数内部为200,99,3,4fmt.Println(arr1)//函数结束后销毁,还是200,3,4,5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/424869.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模拟退火算法(SA算法)求解实例---旅行商问题 (TSP)

目录 一、采用SA求解 TSP二、 旅行商问题2.1 实际例子&#xff1a;求解 6 个城市的 TSP2.2 **求解该问题的代码**2.3 代码运行过程截屏2.4 代码运行结果截屏&#xff08;后续和其他算法进行对比&#xff09; 三、 如何修改代码&#xff1f;3.1 减少城市坐标&#xff0c;如下&am…

文件格式转换:EXCEL和CSV文件格式互相转换

目录 1.EXCEl和CSV文件格式互相转换1.1首先安装所需的Python包1.2excel转换为csv代码如下&#xff1a;1.3csv转换为excel代码如下&#xff1a; 由于excel文件在数学建模数据处理当中的局限性&#xff0c;我们通常把excel文件转换为csv文件来处理&#xff0c;下面是相关的代码&a…

用网卡的ap模式抓嵌入式设备的网络包

嵌入式设备不像pc上&#xff0c;有一些专门的工具比如wareshark来抓包&#xff0c;嵌入式设备中&#xff0c;有的可能集成了tcpdump&#xff0c;可以用来进行简单的抓包&#xff0c;但是不方便分析&#xff0c;况且有的嵌入式设备不一定就集成了tcpdump工具。 关于tcpdump工具…

Hibernate基础

Hibernate基础总结 有利的条件和主动的恢复产生于再坚持一下的努力之中&#xff01; 好久没更新了&#xff0c;今天入门了Hibernate&#xff0c;由于之前学习了MyBatis&#xff0c;初步感觉二者的底层实现思想有很多相似之处&#xff0c;下面让我们以一个入门Demo的形式感受一…

AIGC实战——多模态模型Flamingo

AIGC实战——多模态模型Flamingo 0. 前言1. Flamingo 架构2. 视觉编码器3. Perceiver 重采样器4. 语言模型5. FIamingo 应用小结系列链接 0. 前言 我们已经学习了文本生成图像模型 DALL.E 2&#xff0c;在本节中&#xff0c;我们将探索另一种多模态模型 Flamingo&#xff0c;它…

Docker上安装mysql

获取 MySQL 镜像 获取镜像。使用以下命令来拉取镜像&#xff1a; 1docker pull mysql:latest 这里拉取的是最新版本的 MySQL 镜像。你也可以指定特定版本&#xff0c;例如&#xff1a; 1docker pull mysql:8.0 运行 MySQL 容器 运行 MySQL 容器时&#xff0c;你需要指定一些…

redis基本数据结构-hash

这里写自定义目录标题 1. redis的数据结构hash1.1 Hash 数据结构的特点1.2 常见命令1.3 适用示例 2. 常见业务场景2.1 用户信息存储2.1.1 场景2.1.2 优势2.1.3 解决方案2.1.4 代码实现 2.2 购物车管理2.2.1 背景2.2.2 优势2.2.3 解决方案2.2.4 代码实现 3. 注意事项&#xff1a…

USB的电气特性

文章目录 一、USB的三种速率及状态切换图1. **附加&#xff08;Attached&#xff09;**2. **供电&#xff08;Powered&#xff09;**3. **复位&#xff08;Reset&#xff09;**4. **地址设置&#xff08;Addressed&#xff09;**5. **配置&#xff08;Configured&#xff09;**…

llama网络结构及源码

目录 模型初始化 config lm_head transformer wte h rms_1/rms_2 attn c_attn c_proj 线性层mlp ln_f rope_cache mask_cache kv_caches tokenizer tokenizer初始化 tokennizer.encoder 位置编码和mask 确定最大文本长度 建立rope_cache 建立mask_cache …

C#/.NET/.NET Core技术前沿周刊 | 第 5 期(2024年9.9-9.15)

前言 C#/.NET/.NET Core技术前沿周刊&#xff0c;你的每周技术指南针&#xff01;记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿&#xff0c;助力技术成长与视野拓宽。 欢迎投稿&…

ICM20948 DMP代码详解(23)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;22&#xff09; 上一回解析完了inv_icm20948_wakeup_mems函数&#xff0c;本回回到inv_icm20948_initialize_lower_driver函数中&#xff0c;继续往下解析。为了便于理解和回顾&#xff0c;再次贴出inv_icm20948_init…

闯关leetcode——26. Remove Duplicates from Sorted Array

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ 内容 Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appear…

Framebuffer应用编程

目录 前言 LCD操作原理 涉及的 API 函数 open函数 ioctl 函数 mmap 函数 Framebuffer程序分析 源码 1.打开设备 2.获取LCD参数 3.映射Framebuffer 4.描点函数 5.随便画几个点 上机实验 前言 本文介绍LCD的操作原理和涉及到的API函数&#xff0c;分析Framebuffer…

Python青少年简明教程:tkinter库入门

Python青少年简明教程&#xff1a;tkinter库入门 tkinter是Python的标准GUI&#xff08;图形用户界面&#xff09;库。它提供了一种快速而简单的方法来创建GUI应用程序。tkinter是Python自带的&#xff0c;无需额外安装&#xff0c;随 Python 安装包一起提供。 在Python 3.x中…

rtems 5.3 qemu realview_pbx_a9 环境搭建:生成 rtems arm 工具链

前言 rtems 是一款比较优秀的 RTOS&#xff0c;官方网址 https://www.rtems.org/ 当前 rtems 最新发布的版本&#xff1a;rtems-5.3 版本&#xff0c; 下载地址 https://ftp.rtems.org/pub/rtems/releases/5/5.3/ rtems 支持的 平台也是比较多的&#xff0c;当前支持 STM32F4…

调制是什么,为什么

一、什么是调制、解调&#xff1f; 调制&#xff1a;将信息承载到满足信道要求的高频信号上的过程就是调制。 解调&#xff1a;解调是调制的逆过程&#xff0c;将有用的信息从高频信号中恢复出来的过程就是解调。 二、为什么需要调制&#xff1f; 通信是为了实现“信息”的传…

【自然语言处理】实验三:新冠病毒的FAQ问答系统

目录 前言 1.新建data_process.py 1.1导入包并定义功能模块1用来读取问题和答案FAQ的文件 1.2功能模块2&#xff1a;进行问题/问题列表处理&#xff08;正则化&#xff0c;分词&#xff09; 1.3功能模块3&#xff1a;处理输入的问题 1.4功能模块4&#xff1a;计算输入问题与问题…

基于双向RRT算法的三维空间最优路线规划matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 单向RRT算法 4.2 双向RRT算法 5.完整程序 1.程序功能描述 基于双向RRT&#xff08;Randomly Exploring Random Trees, 随机探索随机树&#xff09;算法的三维空间最优路径规划是一种解…

Java | Leetcode Java题解之第406题根据身高重建队列

题目&#xff1a; 题解&#xff1a; class Solution {public int[][] reconstructQueue(int[][] people) {Arrays.sort(people, new Comparator<int[]>() {public int compare(int[] person1, int[] person2) {if (person1[0] ! person2[0]) {return person2[0] - perso…

【目标检测数据集】锯子数据集1107张VOC+YOLO格式

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1107 标注数量(xml文件个数)&#xff1a;1107 标注数量(txt文件个数)&#xff1a;1107 标注…