Golang(一):基础、数组、map、struct

目录

hello world

变量

常量,iota

函数

init函数和导包过程 

指针

defer

数组和动态数组

固定长度数组

遍历数组

动态数组

len 和 cap

截取

切片的追加

map

四种声明方式

遍历map

删除

查看键是否存在

结构体

声明

作为形参

方法

封装

 继承

多态

类型断言


配置:

一文轻松实现在VSCode中编写Go代码_vscode 开发go-CSDN博客

hello world

package main

//导入包
import "fmt"

//主函数,入口函数
func main() { //大括号必须和函数在同一行
	//打印输出
	fmt.Println("hello go")
}

导入多个包:

import "fmt"
import "time"

or

import(
	"fmt"
	"time"
)

变量

四种定义方式

func main() {
	var a int
	fmt.Print(a) //默认为0

	var b int = 3
	fmt.Print(b) //3

	var c = 10
	fmt.Print(c) //10
	fmt.Printf("c is %T", c) //c is int

	d := 3.45
	fmt.Printf("d = %f", d) //d=3.450000
}

第四种方法只能使用于局部变量,例如下面这张方法是不可以的:

a :=200
//non-declaration statement outside function body
func main() {
	fmt.print(a)
}

声明多个变量

func main() {
	var a, b = 3, "asdad"
	fmt.Print(a, b)

	var c, d int = 3, 4
	fmt.Print(c, d)

	var (
		e int = 4
		f     = "aeasd"
	)
	fmt.Print(e, f)

	g, h := 9, false
	fmt.Println(g, h)
}

数据类型转换

一、强制类型转换 

        但是只有相同底层类型的变量之间可以进行相互转换(如将 int16 和 int32 相互转换,float 类型和 int 类型相互转换),不同底层类型的变量相互转换时会引发编译错误(如 bool 类型和 int 类型,string 与 int 类型之间的转换):

  

二、 strconv包:字符串和数值类型的相互转换 

    1. Itoa():整型转字符串  integer to alphanumeric 

    2. Atoi():字符串转整型 alphanumeric to integer 

    3. Parse 系列函数(str转其他): ParseBool()、ParseInt()、ParseUint()、ParseFloat() 

    4.Format 系列函数(其他转str): FormatBool()、FormatInt()、FormatUint()、FormatFloat() 

    5.Append 系列函数(其他转str后加到切片中): AppendBool()、AppendFloat()、AppendInt()、AppendUint() 

  

 golang的数据类型

golang 的数据类型_golang数据类型-CSDN博客

常量,iota

常量不允许重复赋值

func main() {
	const PI float32 = 3.14
	fmt.Printf("PI: %v\n", PI)
	const a = 90
	fmt.Printf("a: %v\n", a)
	a = 99 //cannot assign to a (neither addressable nor a map index expression)
}

常量可以枚举

const (
    Unknown = 0
    Female = 1
    Male = 2
)

可以使用iota实现自增赋值,例如下面这种一个一个赋值很繁琐

const (
    CategoryBooks    = 0
    CategoryHealth   = 1
    CategoryClothing = 2
)

于是:

const (
    CategoryBooks = iota // 0
    CategoryHealth       // 1
    CategoryClothing     // 2
)

在每个枚举中,iota从0开始,每行递增

也可以在第一行使用公式,下面所有行都会使用同样的公式

const (
	CategoryBooks = 10 * iota //0
	CategoryHealth   //10
	CategoryClothing //20
)

公式在中途也可以变化,iota的值不会中断

const (
	CategoryBooks    = 10 * iota //0
	CategoryHealth               //10
	CategoryClothing             //20

	a = 100 * iota        //300
	b                 //400
	c     //500
)

注意,iota只能在const中使用

函数

// 普通函数
func foo1(x int, y int) int {
	return x + y
}

func foo2() {
	fmt.Printf("\"hello\": %v\n", "hello")
}

// 多返回值函数
func foo3(x, y int) (int, string) {
	return 9, "asdad"
}

// 给返回值命名
func foo4() (r1 int, r2 string) {
	fmt.Printf("r1: %v\n", r1) //0
	fmt.Printf("r2: %v\n", r2) //""
	//说明已经命名的返回值就是一个局部变量,具有默认值

	r1 = 9
	r2 = "qwqw"
	return
}

func main() {
	a := foo1(1, 2)
	fmt.Printf("a: %v\n", a)

	foo2()

	c, d := foo3(1, 2)
	fmt.Printf("c: %v\n", c)
	fmt.Printf("d: %v\n", d)

	e, f := foo4()
	fmt.Printf("e: %v\n", e)
	fmt.Printf("f: %v\n", f)
}

init函数和导包过程 

 lib1:

package lib1
import (
	"fmt"
	"lib2"
)
func init() {
	fmt.Println("lib1 init")
	lib2.Lib2_test()
}
func Lib1_test() {
	fmt.Println("lib1_test")
}

lib2:

package lib2
import "fmt"
func init() {
	fmt.Println("lib2 init")
}
func Lib2_test() {
	fmt.Println("lib2_test")
}

main:

package main
import (
	"fmt"
	"lib1"
)
func main() {
	fmt.Print("main")
	lib1.Lib1_test()
// 	lib2 init
// lib1 init
// lib2_test
// mainlib1_test
}

值得注意的是,包中的函数必须是大写字母开头的,这样这个函数才能在包外被调用,可以看成是java中public的一种形式

 在golang中,如果导入了包,却不调用包的方法,会报错

但是如果我只想执行包的init函数却不使用包中的方法,可以使用匿名包,这样不能调用包的方法,但是会执行init

import (
	"fmt"
	_ "lib1"
)
func main() {
	fmt.Print("main")
}

可以给包起别名

import (
	"fmt"
	mylib1 "lib1"
)
func main() {
	fmt.Print("main")
	mylib1.Lib1_test()

}

指针

跟c语言一样  

package main

//导入包
import "fmt"

func changevalue(p *int) { //申明 p 为指针型变量,指向一个int型的变量,p本身存储的是这个int变量的地址
	*p = *p * 10  //*p 表示指向的这个变量本身
}

func main() {
	a := 10
	changevalue(&a)   //&a表示a的地址
	fmt.Printf("a: %v\n", a) //100
}
package main

//导入包
import "fmt"

func changevalue(a *int, b *int) {
	temp := *a
	*a = *b
	*b = temp
}

func main() { //大括号必须和函数在同一行
	a := 10
	b := 20
	changevalue(&a, &b)
	fmt.Printf("a: %v\n", a) //20
	fmt.Printf("b: %v\n", b) //10
}

二级指针,指向指针的指针

package main

//导入包
import (
	"fmt"
)

// 普通函数

func main() {
	a := 10
	var p *int = &a
	var p1 **int = &p

	fmt.Println(&p) //0xc000070030
	fmt.Println(p1) //0xc000070030

}

defer

在当前函数体的最后运行

func main() {
	defer fmt.Println("main end")
	fmt.Printf("\"alalal\": %v\n", "alalal")
// 	"alalal": alalal
//   main end
}

如果存在多个defer,则遵循 栈 的原则

func main() {
	defer fmt.Println("main end1")
	defer fmt.Println("main end2")
	fmt.Printf("\"alalal\": %v\n", "alalal")
	// "alalal": alalal
	// main end2
	// main end1
}

在函数调用中,defer在return之后,这个很好理解,因为defer应该在函数体最后执行,最先入栈,在return之后

func returnfunc() int {
	fmt.Println("return end")
	return 0
}

func testfunc() int {
	defer fmt.Println("func end")
	return returnfunc()
}
func main() {
	testfunc()
	// 	return end
	// func end
}

数组和动态数组

固定长度数组

func main() {
	var myarray [10]int
	myarray2 := [10]int{1, 2, 3, 4}
}

固定长度数组需要指定数组长度,且有默认值

当固定长度数组作为形参时,进行的是值传递,而不是引用传递

func change_array(myarry [4]int) {
	myarry[0] = 100
}
func main() {
	myarray2 := [4]int{1, 2, 3, 4}

	change_array(myarray2)
    //myarray2的值不改变
}

而且当函数形参是固定长度数组时,传入其他长度的数组也不可以,非常的不方便

遍历数组

func main() {
	var myarray [10]int
	myarray2 := [10]int{1, 2, 3, 4}
	for i := 0; i < len(myarray); i++ {
		fmt.Printf("myarray[i]: %v\n", myarray[i])
	}
	for index, value := range myarray2 {
		fmt.Printf("index:%d,value:%d\n", index, value)
	}
}

 也可以只遍历下标:

	myarray2 := [10]int{1, 2, 3, 4}
	for index := range myarray2 {
		fmt.Printf("index:%d\n", index)
	}

动态数组

也叫  切片

func change_array(myarry []int) {
	myarry[0] = 100
}
func main() {
	myarray2 := []int{1, 2, 3, 4}
	fmt.Printf("%T \n", myarray2) //[]int
	change_array(myarray2)
	for index, value := range myarray2 {
		fmt.Printf("index:%d,value:%d\n", index, value)
	} //myarray2的值改变
}

多种声明方式

func main() {
	slice1 := []int{}
	slice1 = make([]int, 3) //开辟三个空间
	fmt.Printf("len(slice): %d, slice1: %v\n", len(slice1), slice1)
	// len(slice): 3, slice1: [0 0 0]

	slice2 := make([]int, 4)
	fmt.Printf("len(slice): %d, slice2: %v\n", len(slice2), slice2)
	// len(slice): 4, slice2: [0 0 0 0]

}

追加元素:

func main() {
	slice1 := []int{}
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 0, cap: 0, slice1: []
	slice1 = append(slice1, 2)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 1, cap: 1, slice1: [2]
}

len 和 cap

这里需要说一下 len 和cap

func main() {
	slice1 := make([]int, 3)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 3, cap: 3, slice1: [0 0 0]
	slice1 = append(slice1, 2)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 4, cap: 6, slice1: [0 0 0 2]
}

当我们为其开辟是空间3时,其默认的cap也是3,cap是系统为数组一次性开辟空间的大小

当我再次加入元素时,长度变为了4,但是cap变成了6,也就是说在加入时自动增加了三个大小的空间

当然我们也可以指定cap

func main() {
	slice1 := make([]int, 3, 5)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 3, cap: 3, slice1: [0 0 0]
	slice1 = append(slice1, 2)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 4, cap: 6, slice1: [0 0 0 2]
	slice1 = append(slice1, 2)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 5, cap: 5, slice1: [0 0 0 2 2]
	slice1 = append(slice1, 2)
	fmt.Printf("len(slice): %d, cap: %d, slice1: %v\n", len(slice1), cap(slice1), slice1)
	// len(slice): 5, cap: 5, slice1: [0 0 0 2 2]

}

当然只有在增加元素超过了len时,才会使用cap增加空间

截取

截取方法和python一样,值得注意的是,这里的截取都是浅拷贝

func main() {
	s := []int{1, 2, 3}
	s1 := s[0:2]

	s1[0] = 100
	fmt.Printf("s1: %v\n", s1)
	fmt.Printf("s: %v\n", s)
	// 	s1: [100 2]
	// s: [100 2 3]

}

如果想实现深拷贝:

func main() {
	s := []int{1, 2, 3}
	s1 := make([]int, 2)

	copy(s1, s)

	s1[0] = 100
	fmt.Printf("s1: %v\n", s1)
	fmt.Printf("s: %v\n", s)
	// s1: [100 2]
	// s: [1 2 3]

}

切片的追加

slice := make([]int, 2, 4)
append_slice := []int{1, 2}
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)
 
slice = append(slice, append_slice...)
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)
 
slice = append(slice, 10, 20)
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)
 
slice = append(slice, 30, 40, 50)
fmt.Printf("slice addr:%p len:%d cap:%d slice:%v\n", slice, len(slice), cap(slice), slice)
 
//output
slice addr:0xc0420540a0 len:2 cap:4 slice:[0 0]
slice addr:0xc0420540a0 len:4 cap:4 slice:[0 0 1 2]
slice addr:0xc04207a080 len:6 cap:8 slice:[0 0 1 2 10 20]
slice addr:0xc04208a000 len:9 cap:16 slice:[0 0 1 2 10 20 30 40 50]

 删除等操作可以查看:

初识go语言之 数组与切片(创建,遍历,删除,插入,复制)_golang创建数组-CSDN博客

map

四种声明方式

声明方式1:

	var mymap map[int]string
	if mymap == nil {
		fmt.Print("mymap is empty\n")
	}
	// mymap is empty

这种情况下给map增加键值对是非法的,因为此时mymap的容量为0

但是如果是下面这种是可以的,因为默认分配了空间:

	var mymap1 = map[int]string{}
	mymap1[0] = "awew"

声明方式2:

可以使用make申请空间,且这个空间是动态可以扩展的

	mymap2 := make(map[int]string, 1)
	mymap2[1] = "aa"
	mymap2[2] = "aa"
	fmt.Printf("mymap2: %v\n", mymap2)

声明方式3:

不主动申请空间,但是其默认是有空间的

	mymap3 := make(map[int]string)
	mymap3[2] = "sad"
	fmt.Printf("mymap3: %v\n", mymap3)

声明方式4:

	mymap4 := map[int]string{
		1: "aa",
		2: "bb",
		3: "cc",
	}
	mymap4[4] = "ee"
	fmt.Printf("mymap4: %v\n", mymap4)

遍历map

	mymap4 := map[int]string{
		1: "aa",
		2: "bb",
		3: "cc",
	}
	mymap4[4] = "ee"
	for key, value := range mymap4 {
		fmt.Printf("key: %v\n", key)
		fmt.Printf("value: %v\n", value)
	}
	// 	key: 1
	// value: aa
	// key: 2
	// value: bb
	// key: 3
	// value: cc
	// key: 4
	// value: ee

删除


	mymap4 := map[int]string{
		1: "aa",
		2: "bb",
		3: "cc",
	}
	mymap4[4] = "ee"
	fmt.Printf("mymap4: %v\n", mymap4)
	delete(mymap4, 4)
	fmt.Printf("mymap4: %v\n", mymap4)
	// mymap4: map[1:aa 2:bb 3:cc 4:ee]
	// mymap4: map[1:aa 2:bb 3:cc]

查看键是否存在

func main() {
    m := make(map[string]int)
    m["张三"] = 10
    m["李四"] = 20
    value, ok := m["张四"]
 
    if ok {
        fmt.Println(value)
    } else {
        fmt.Println("查无此人")
    }
}

当map作为形参时,也是引用传递 

golang的map-CSDN博客

Golang底层原理剖析之map_golang map底层-CSDN博客

结构体

这里的结构体可以看出是  类 

声明

type Book struct {
	name  string
	price int
}

func main() {
	var mathbook Book
	mathbook.name = "lalal"
	mathbook.price = 12
	fmt.Printf("mathbook: %v\n", mathbook)
	// mathbook: {lalal 12}

}

作为形参

type Book struct {
	name  string
	price int
}

func changebook(book Book) {
	book.price = 100
}

func changebook2(book *Book) {
	book.price = 100
}

func main() {
	var mathbook Book
	mathbook.name = "lalal"
	mathbook.price = 12
	changebook(mathbook)
	fmt.Printf("mathbook: %v\n", mathbook)
	// mathbook: {lalal 12}
	changebook2(&mathbook)
	fmt.Printf("mathbook: %v\n", mathbook)
	// mathbook: {lalal 100}

}

这说明作为形参传递是 值传递,而不是引用传递

方法

结构体方法的定义:

type Book struct {
	name  string
	price int
}

func (this Book) show() {
	fmt.Printf("this.name: %v\n", this.name)
	fmt.Printf("this.price: %v\n", this.price)
}

func (this Book) changeprice(new_price int) {
	this.price = new_price
}

func (this *Book) changeprice1(new_price int) {
	this.price = new_price
}

func main() {
	var mathbook Book
	mathbook.name = "lalal"
	mathbook.price = 12
	mathbook.show()
	// mathbook: {lalal 12}

	mathbook.changeprice(112)
	mathbook.show()

	mathbook.changeprice1(112)
	mathbook.show()

	// 	this.name: lalal
	// this.price: 12
	// this.name: lalal
	// this.price: 12
	// this.name: lalal
	// this.price: 112

}

当调用mathbook.changeprice()时相当于changeprice(mathbook),实参和行参都是类型 Book,可以接受。此时在changeprice()中的t只是参数t的值拷贝,所以method1()的修改影响不到main中的t变量。

当调用mathbook.changeprice1()=>changeprice1(mathbook),这是将 Book 类型传给了 *Book 类型,go可能会取 mathbook 的地址传进去:changeprice1(&mathbook)。所以 changeprice1() 的修改可以影响 mathbook

由于结构体作为形参是指传递,所以在改变参数时务必使用 地址传参

封装

在go中的struct中,类名、属性名、方法名大写表示对外可以访问,也就是java中的public

 继承

type Person struct {
	name string
	sex  string
}

func (this *Person) Eat() {
	fmt.Print("person eat")
}

type Super_man struct {
	Person  //继承Person类
	level int
}

func (this *Super_man) Eat() { //重写父类方法
	fmt.Print("super_man eat")
}

func (this *Super_man) Fly() { //定义新的方法
	fmt.Print("super_man fly")
}

func main() {
//两种声明对象的方式
	super_man1 := Super_man{Person{"lee", "male"}, 2}

	var super_man2 Super_man
	super_man2.name = "lee"
	super_man2.sex = "male"
	super_man2.level = 2

	super_man1.Fly()
	super_man2.Fly()
}

多态

type Animal interface {
	Sleep()
	GetColor() string
}

type Cat struct {
	color string
}

func (this *Cat) Sleep() {
	fmt.Print("CAT IS SLEEPING\n")
}
func (this *Cat) GetColor() string {
	return this.color
}

type Dog struct {
	color string
}

func (this *Dog) Sleep() {
	fmt.Print("Dog IS SLEEPING\n")
}
func (this *Dog) GetColor() string {
	return this.color
}

func main() {
	var animal Animal
	animal = &Cat{"blue"}
	fmt.Printf("animal.GetColor(): %v\n", animal.GetColor())
	animal.Sleep()
	// animal.GetColor(): blue
	animal = &Dog{"black"}
	fmt.Printf("animal.GetColor(): %v\n", animal.GetColor())
	animal.Sleep()
	// 	animal.GetColor(): blue
	// CAT IS SLEEPING
	// animal.GetColor(): black
	// Dog IS SLEEPING
}

上面这部分代码定义了一个接口  Animal,其中定义了2个方法

Cat和Dog类只需要完全实现这2个方法(也可以有接口中没有定义的方法), 就可以实现和Animal接口的多态,可以用鸭子类型理解

为了更加直观的实现多态:

func animal_is_sleeping(animal Animal) {
	animal.Sleep()
}

func main() {
	mycat := Cat{"blue"}
	animal_is_sleeping(&mycat)
	// CAT IS SLEEPING
}

在golang中,只能借助接口实现多态,使用父类是无法实现多态的,当然,如果B的父类是A,而A实现了接口C的方法,那么B也可以与C形成多态

interface{}

interface接口可以跟所有的类形成多态:

func myshow(arg interface{}) {
	fmt.Println(arg)
}

func main() {
	myshow(12)
	myshow("asdas")
	myshow([]int{1, 2, 3})
	myshow(map[int]int{1: 2, 2: 3})
	// 	12
	// asdas
	// [1 2 3]
	// map[1:2 2:3]
}

类型断言

可以判断接口现在对应的类是哪个:

	var myanimal Animal
	myanimal = &Cat{"blue"}

	value, ok := myanimal.(*Cat)
	fmt.Printf("ok: %v\n", ok)
	fmt.Printf("value: %v\n", value)

	value2, ok2 := myanimal.(*Dog)
	fmt.Printf("ok: %v\n", ok2)
	fmt.Printf("value: %v\n", value2)

	// 	ok: true
	// value: &{blue}
	// ok: false
	// value: <nil>

Go Struct超详细讲解 - 掘金

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

笔记软件功能多样的是哪款?做笔记的软件哪个好用

在快节奏的现代生活中&#xff0c;笔记软件已成为我们提高工作效率、记录生活点滴的重要工具。想象一下&#xff0c;在繁忙的工作中&#xff0c;你能够快速记录下关键信息&#xff0c;或在灵感迸发时及时捕捉&#xff0c;这是多么方便高效。 一款功能多样的笔记软件&#xff0…

Syncovery for Mac:高效文件备份和同步工具

Syncovery for Mac是一款专为Mac用户设计的文件备份和同步工具&#xff0c;凭借其高效、安全和易用的特点&#xff0c;深受用户好评。 Syncovery for Mac v10.14.2激活版下载 该软件具备强大的备份功能&#xff0c;支持多种备份方案和数据格式&#xff0c;用户可以根据需求轻松…

Python教学入门:函数

在 Python 中&#xff0c;def 关键字用于定义函数。函数是一段可重用的代码块&#xff0c;用于执行特定的任务或操作。通过定义函数&#xff0c;可以将一段代码封装起来&#xff0c;使其可以在程序中被多次调用&#xff0c;提高代码的复用性和可维护性。 下面是 def 函数定义的…

pandas/python 一个实战小案例

上次写坦克游戏的时候&#xff0c;接触了一点pandas&#xff0c;当时只是简单了解了一下如何遍历行和列并获取值来替换图片&#xff0c;想更多了解pandas。正好有一些数据需要筛选&#xff0c;试试能不能用通过代码实现。虽然总的来说不复杂&#xff0c;但由于原始数据在命名、…

如何训练猫出门不害怕:耐心做好这些训练,轻松get能溜的小猫

一般我们外出见到的都是遛狗的&#xff0c;溜猫的相对少见&#xff0c;一方面是因为猫咪是喜欢安静独处的小动物&#xff0c;另一方面是糟乱的环境也容易引起猫咪的应激。对于是否应该“溜猫”&#xff0c;有两个极端的阵营。一些铲屎官认为应尊重猫的天性&#xff0c;胆小不爱…

如何使用AI写作扩写文章?看完这篇学会扩写

如何使用AI写作扩写文章&#xff1f;在数字化时代的浪潮下&#xff0c;人工智能&#xff08;AI&#xff09;已经深入渗透到我们生活的各个领域&#xff0c;其中&#xff0c;AI写作扩写技术更是以其高效、便捷的特点受到了广大用户的青睐。它不仅极大提升了写作效率&#xff0c;…

Leetcode算法训练日记 | day29

一、递增子序列 1.题目 Leetcode&#xff1a;第 491 题 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&…

硬件?、嘉立创EDA画PCB规则设计

1、打开规则设计 设置单位为mil 点击全部 将安全距离设置为8mil&#xff0c;这个8mil是目前很多生产PCB的工厂可以做的&#xff0c;如果距离设置的更小也就是性能要求更高&#xff0c;相应的生产成本也高元件到元件的距离设置为20mil 2、设置导线的宽度规则&#xff0c;可以对v…

第G6周:CycleGAN实践

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、CycleGAN原理 &#xff08;一&#xff09;CycleGAN的原理结构&#xff1a; CycleGAN&#xff08;循环生成对抗网络&#xff09;是一种生成对抗网络&…

思维导图软件Xmind for Mac 中文激活版 支持M

XMind是一款非常受欢迎的思维导图软件&#xff0c;它应用了Eclipse RCP软件架构&#xff0c;注重易用性、高效性和稳定性&#xff0c;致力于帮助用户提高生产率。 Xmind for Mac 中文激活版下载 XMind的程序主体由一组插件构成&#xff0c;包括一个核心主程序插件、一组Eclipse…

文件后缀变成.halo? 如何恢复重要数据

.halo 勒索病毒是什么&#xff1f; .halo勒索病毒是一种恶意软件&#xff0c;属于勒索软件&#xff08;Ransomware&#xff09;的一种。这种病毒会加密用户计算机上的文件&#xff0c;并要求受害者支付赎金才能获取解密密钥&#xff0c;从而恢复被加密的文件。勒索软件通常会通…

力扣(leetcode) 42. 接雨水 (带你逐步思考)

力扣(leetcode) 42. 接雨水 &#xff08;带你逐步思考&#xff09; 链接&#xff1a;https://leetcode.cn/problems/trapping-rain-water/ 难度&#xff1a;hard 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多…

【方便 | 重要】#LLM入门 | Agent | langchain | RAG # 3.7_代理Agent,使用langchain自带agent完成任务

大型语言模型&#xff08;LLMs&#xff09;虽强大&#xff0c;但在逻辑推理、计算和外部信息检索方面能力有限&#xff0c;不如基础计算机程序。例如&#xff0c;LLMs处理简单计算或最新事件查询时可能不准确&#xff0c;因为它们仅基于预训练数据。LangChain框架通过“代理”(…

机器学习在安全领域的应用:从大数据中识别潜在安全威胁

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

Ubuntu20.04 ISAAC SIM仿真下载使用流程(4.16笔记补充)

机器&#xff1a;华硕天选X2024 显卡&#xff1a;4060Ti ubuntu20.04 安装显卡驱动版本&#xff1a;525.85.05 参考&#xff1a; What Is Isaac Sim? — Omniverse IsaacSim latest documentationIsaac sim Cache 2023.2.3 did not work_isaac cache stopped-CSDN博客 Is…

LeetCode in Python 704. Binary Search (二分查找)

二分查找是一种高效的查询方法&#xff0c;时间复杂度为O(nlogn)&#xff0c;本文给出二分查找的代码实现。 示例&#xff1a; 代码&#xff1a; class Solution:def search(self, nums, target):l, r 0, len(nums) - 1while l < r:mid (l r) // 2if nums[mid] > ta…

C++11 数据结构1 线性表的概念,线性表的顺序存储,实现,测试

一 线性表的概念 线性结构是一种最简单且常用的数据结构。 线性结构的基本特点是节点之间满足线性关系。 本章讨论的动态数组、链表、栈、队列都属于线性结构。 他们的共同之处&#xff0c;是节点中有且只有一个开始节点和终端节点。按这种关系&#xff0c;可以把它们的所有…

MC9S12A64 程序烧写方法

前言 工作需要对MC9S12A64 单片机进行程序烧写。 资料 MC9S12A64 单片机前身属于 飞思卡尔半导体&#xff0c;后来被恩智浦收购&#xff0c;现在属于NXP&#xff1b; MC9S12A64 属于16位S12系列&#xff1b;MC9S12 又叫 HCS12。 数据手册下载连接 S12D_16位微控制器 | N…

[大模型]TransNormerLLM-7B 接入 LangChain 搭建知识库助手

TransNormerLLM-7B 接入 LangChain 搭建知识库助手 环境准备 在 autodl 平台中租赁一个 3090/4090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其…

简单实用的备忘录小工具 记事提醒备忘效果超好

在这个信息爆炸的时代&#xff0c;我们每个人都需要处理大量的信息和任务。有时候&#xff0c;繁忙的生活和工作会让我们感到压力山大。幸运的是&#xff0c;现在有很多简单实用的软件工具&#xff0c;像得力的小助手一样&#xff0c;帮助我们整理思绪&#xff0c;提高效率&…