【Go 快速入门】数组 | 切片 | 映射 | 函数 | 结构体 | 方法和接收者

文章目录

    • 数组
    • 切片
      • append 函数
      • copy 函数
      • 删除元素
    • 映射
      • delete 函数
    • 函数
      • init 特殊的函数
      • defer 语句
      • panic / recover 错误处理
    • 类型
      • 结构体
      • 内存对齐
      • JSON 序列化与反序列化
      • 方法和接收者

项目代码地址:03-ArraySliceMapFuncStruct

数组

基本格式:var 数组变量名 [元素数量]T

  • 数组长度必须是常量或者常量表达式
  • 数组大小不可以修改
  • 数组不支持负数索引
  • ... 自动推导第一维数组长度
// Array 1
func function01() {const lenA = 2var a [lenA + 1]int // 常量表达式定义数组长度// var lenB = 3// b := [lenB]int{} 错误!变量不可用于定义数组长度var b = [1]bool{true}                   // 基本初始化var c [2]string = [...]string{"A", "B"} // 省略号自行推断数组长度d := [...]int{1: -1, 3: 5}              // 索引值初始化fmt.Println(a, b, c, d) // [0 0 0] [true] [A B] [0 -1 0 5]// 第一维可自动推导长度citys := [...][3]string{{"北京", "上海", "广州"},{"重庆", "湖南", "武汉"},}fmt.Println(citys) // [[北京 上海 广州] [重庆 湖南 武汉]]// 二维数组遍历for _, v1 := range citys {for _, city := range v1 {fmt.Print(city)}} // 北京上海广州重庆湖南武汉
}
  • 数组是值类型,赋值和传参会拷贝副本
  • 数组同类型,可以进行比较
// Array 2
func function02() {a := [...]int{1, 2}b := ab[0] = 3fmt.Println(a, b) // [1 2] [3 2]for i, length := 0, len(a); i < length; i++ {fmt.Printf("%v ", a[i])} // 1 2fmt.Println()// 同类型且内部元素可比较,那么可以使用 == 和 != 比较两个数组fmt.Printf("%#v %#v %T %T %t %t\n", a, b, a, b, b == a, b != a) // [2]int{1, 2} [2]int{3, 2} [2]int [2]int false true
}

切片

基本格式:var 切片变量名 []T

切片表达式:a[low: high: max],满足 0 <= low <= high <= max <= cap(a),仅 low 可以省略(默认 0)

切片不同于数组,切片长度不固定,可以通过 append 向切片动态添加元素,并且会自动扩容。切片是一个引用类型,可以基于字符串、数组、切片及其指针,通过切片表达式得到切片。

// Slice 1
func function03() {a := [5]int{1, 2, 3, 4: -1} // 1 2 3 0 -1strA := "Hello Golang"ptrStrA := new(string)ptrStrA = &strAsliceA := a[1:5]                             // 基于数组sliceStrA := strA[6:]                        // 基于字符串slicePtrStrA := (*ptrStrA)[:5]               // 基于字符串指针fmt.Println(sliceA, sliceStrA, slicePtrStrA) // [2 3 0 -1] Golang HellosliceB := sliceA[2:]           // 基于切片fmt.Println(sliceB)            // [0 -1]sliceB[0] = -2                 // 引用类型fmt.Println(a, sliceA, sliceB) // [1 2 3 -2 -1] [2 3 -2 -1] [-2 -1]
}

切片表达式第三维 max,表示当前截取出的切片的容量 cap = max - low。即 low 是起始位置,highlen 长度的结尾位置后一位(左闭右开),maxcap 容量的结尾位置后一位。

在这里插入图片描述

如果想要动态创建切片,需要使用内置 make 函数:make([]T, size, cap)

使用 make 函数,可以一次性将切片所需容量申请到位,可以避免小切片的多次动态扩容。

// Slice 2
func function04() {a := [...]int{0, 1, 2, 3, 4, 5, 6, 7}fmt.Println(a, len(a), cap(a)) // [0 1 2 3 4 5 6 7] 8 8sliceA1 := a[1:5]fmt.Println(sliceA1, len(sliceA1), cap(sliceA1)) // [1 2 3 4] 4 7sliceA2 := a[1:5:7]fmt.Println(sliceA2, len(sliceA2), cap(sliceA2)) // [1 2 3 4] 4 6b := make([]int, 1, 4)b = append(b, 2, 3)fmt.Println(b) // [0 2 3]
}
  • nil 切片和 empty 切片

    • nil 切片,不仅没大小容量,且不指向任何底层数组;

    • empty 切片,没大小容量,但指向一个特殊的内存地址 zerobase — 所有 0 字节分配的基地址

判断一个切片是否为空,使用 len(a) == 0 而不要直接使用 a == nil,因为切片元素不是直接存储的值,所以也不允许切片之间使用 == 比较,唯一合法可以和 nil 进行比较。

// Slice 3
func function05() {var s1 []int // nil 切片,不仅没大小容量,且不指向任何底层数组s2 := []int{}s3 := make([]int, 0) // s2、s3 都是 empty 切片,没大小容量,但指向一个特殊的内存地址 zerobase - 所有 0 字节分配的基地址fmt.Println(len(s1), len(s2), len(s3), cap(s1), cap(s2), cap(s3)) // 0 0 0 0 0 0fmt.Println(s1 == nil, s2 == nil, s3 == nil)                      // true false falsefmt.Printf("%#v %#v %#v\n", s1, s2, s3)                           // []int(nil) []int{} []int{}// fmt.Println(s1 == s2) // 切片之间不允许直接使用 == 比较,唯一可以和 nil 进行比较
}

append 函数

基本格式:append(slice []Type, elems ...Type) []Type

切片在使用 append 函数后,可能会造成扩容,改变底层数组的地址,Go 编译器也不允许调用 append 函数后不使用其返回值,所以通常使用原变量接收 append 函数的返回值。

  • 可以对 nil 切片直接使用 append
  • 可以一次性添加多个元素到末尾
// Slice 4
func function06() {var a []int // nil 切片a = append(a, 2, 3, 4)fmt.Println(a, len(a), cap(a)) // [2 3 4] 3 3
}

copy 函数

基本格式:copy(destSlice, srcSlice []T) int

不希望两个切片共享底层同一个数组,可以使用 copy 函数,执行深拷贝

// Slice 5
func function07() {a := []int{1, 2, 3}var b = make([]int, len(a), len(a))copy(b, a)        // 深拷贝fmt.Println(a, b) // [1 2 3] [1 2 3]b[0] = -1fmt.Println(a, b) // [1 2 3] [-1 2 3]
}

删除元素

  • 借助切片本身的特性来删除索引 x 元素:append(a[:x], a[x + 1:]...)
  • 借助 copy 来删除索引 x 元素:copy(a[x:], a[x + 1:]),最终元素需要少一位输出
// Slice 6
func function08() {a := []int{1, 2, 3}b := append(a[:1], a[2:]...)fmt.Println(b) // [1 3]copy(a[1:], a[2:])fmt.Println(a[:len(a)-1]) // [1 3]
}

映射

基本格式:map[KeyType]ValueType

Go 中的 map 是引用类型,并且必须初始化才能使用,不像 nil 切片能直接使用。

// Map 1
func function09() {var a map[string]intb := map[string]int{}c := make(map[string]int)fmt.Println(a == nil, b == nil, c == nil) // true false false
}

同样使用 make 函数初始化:make(map[T]T, cap),第二个参数表示初始化创建的 map 容量大小。

判断键值是否存在:val, ok := map[key]

  • key 存在,返回 key 对应 val,且 ok 为 true
  • key 不存在,返回 值类型零值,ok 为 false
// Map 2
func function10() {b := map[string]int{"周一": 1,"周二": 2,}b["周三"] = 3// 遍历 mapfor k, v := range b {println(k, v)}// 取值第二个返回值,表示是否存在该元素if v, ok := b["周二"]; ok {fmt.Println(v)}
}

delete 函数

基本格式:delete(m map[Type]Type1, key Type)

// Map 3
func function11() {m := make(map[int]string, 4)m[1] = "Python"m[2] = "Go"m[3] = "Lua"for _, v := range m {fmt.Println(v)} // Python Go Luadelete(m, 2)for _, v := range m {fmt.Println(v)} // Python Lua
}

函数

基本格式:

func 函数名(参数)(返回值) {函数体
}

Go 语言中支持函数、匿名函数和闭包,并且函数在 Go 语言中属于“一等公民”。

  • 多返回值
// 多返回值
func function13(a int, b int) (int, int) {return b, a
}
  • 返回值命名
// 返回值命名
func function12(x, y int) (ret int) {ret = x + yreturn
}
  • 变参函数
// 变参函数
func function14(nums ...int) int {sum := 0for _, v := range nums {sum = sum + v}return sum
}

变参传递:

func function14_1() {ret := function14([]int{1, 2, 3}...)fmt.Print(ret) // 6
}
  • 函数参数
// 函数参数
func function15(a, b int, f func(int, int) int) {f(a, b)return
}
  • 函数变量,匿名函数
// 函数变量
func function16() {add := func(a, b int) int {return a + b}function15(1, 2, add)
}
  • 函数返回值,函数闭包
// 函数返回值
func function17() func(int) int {y := 1return func(x int) int {return x + y}
}
  • 递归

闭包也可以是递归的,但要求在定义闭包之前用类型化的 var 显式声明闭包。

// 递归
func function20() {var dfs func(int) intdfs = func(x int) int {if x > 3 {return 3}return x + dfs(x+1)}ret := dfs(1)fmt.Print(ret) // 1+2+3+3 == 9
}

init 特殊的函数

程序启动时自动执行每个包的 init 函数

func init() {fmt.Println("main init")
}

defer 语句

Go 语言中的 defer 语句会将其后面跟随的语句进行延迟处理。

defer 归属的函数即将返回时,将延迟处理的语句按 defer 定义的逆序进行执行,也就是说,先被 defer 的语句最后被执行,最后被 defer 的语句,最先被执行。

// defer
func function18() {f1 := func() {fmt.Print(1)}f2 := func() {defer f1()fmt.Print(2)}defer func() {fmt.Print(3)defer f2()}() // 321return
}

Go 函数中 return 语句在底层并不是原子操作,它分为给返回值赋值和 RET 指令两步。

defer 语句执行的时机就在返回值赋值操作后,RET 指令执行前。如下图所示:(参考)

在这里插入图片描述

  • defer 注册要延迟执行的函数时该函数所有的参数都需要确定其值
func calc(index string, a, b int) int {ret := a + bfmt.Println(index, a, b, ret)return ret
}func function19() {x := 1y := 2defer calc("AA", x, calc("A", x, y))x = 10defer calc("BB", x, calc("B", x, y))y = 20
}

A 1 2 3
B 10 2 12
BB 10 12 22
AA 1 3 4


panic / recover 错误处理

panic 的一种常见用法是:当函数返回我们不知道如何处理(或不想处理)的错误值时,中止操作。

recover 可以阻止 panic 中止程序,并让它继续执行。

举例:

当其中一个客户端连接出现严重错误,服务器不希望崩溃。 相反,服务器希望关闭该连接并继续为其他的客户端提供服务。

注意:

  • 必须在 defer 的函数中调用 recover,不可以直接 defer recover()
  • defer 一定要在可能引发 panic 的语句之前定义
// panic, recover
func function21() {defer func() {if err := recover(); err != nil {fmt.Println("recover err:", err)}}() // recover err: function error!func() {panic("function error!")}()fmt.Println("After panic") // 不会执行
}

当跳出引发 panic 的函数时,defer 会被激活, 其中的 recover 会捕获 panic,并且 recover 的返回值是在调用 panic 时抛出的错误。

最后一行代码不会执行,因为 main 程序的执行在 panic 点停止,并在继续处理完 defer 后结束。


类型

  • 类型定义

语法规则:type NewType SourceType

类型定义定义了全新类型,该类型与源类型底层类型相同。

  • 类型别名

语法规则:type TypeAlias = Type

类型别名和其源类型本质上同属一个类型。

// 类型定义,类型别名
func function22() {type MyInt int // 类型定义var a int = 1var b MyIntb = MyInt(a)          // 必须显示转换fmt.Printf("%T\n", b) // main.MyInttype MyFloat = float32 // 类型别名var A float32 = 0.1var B MyFloatB = A                 // 只是别名,本质同属一个类型fmt.Printf("%T\n", B) // float32
}

从上述输出结果来看,类型定义是表示 main 包下定义的类型 MyInt,而类型别名仍然是源类型,类型别名只存在源代码中,编译时会自动替换为原来的类型。


结构体

基本格式:

type 类型名称 struct {字段名称 字段类型
}

在声明结构体字段时,也可以指定标签 tag,形如 key1:"value1" key2:"value2",并且需要用反引号包裹。标签信息可以在程序运行时通过反射机制被读取,比如被用于在结构体变量和 JSON 数据之间转换时,通过 tag 建立联系。

// 结构体
type Info struct {Email stringPhone string
}type Person struct {ID      int64 `json:"id" form:"id"` // tag 标签Name    stringContact Info 
}
  • 结构体不能包含自己,但可以包含它的指针类型
type Node struct {val int next *Node
}
  • 结构体初始化
func function23() {a := Info{Email: "123@163.com",Phone: "123456",}// 结构体简单,按顺序初始化b := Info{"456@163.com","987654",}fmt.Printf("%T %T\n", a, Person{}) // main.Info main.Personfmt.Println(a, b) // {123@163.com 123456} {456@163.com 987654}
}
  • 匿名结构体
func function24() {a := struct {x, y int}{1, 2,}fmt.Println(a) // {1 2}
}
  • 结构体嵌套
func function27() {type Student struct {Name stringInfo // 结构体嵌套}var a Studenta = Student{Name: "Cauchy",Info: Info{Email: "123@163.com",Phone: "123456",},}fmt.Println(a.Name, a.Email, a.Phone) // Cauchy 123@163.com 123456
}
  • 自定义结构体构造函数

一般结构体较为复杂,则可以使用返回指针对象。

// 自定义结构体构造函数
func NewInfo() *Info {return &Info{Email: "123@163.com",Phone: "123456",}
}func function29() {a := NewInfo()fmt.Println(a) // &{123@163.com 123456}
}

内存对齐

内存对齐同 C++ 语言类似,不过多阐述。

需要注意的是,一个空的结构体不占用内存空间,但是当一个结构体最后一个字段是空结构体,编译器会额外填充 1 字节。

func function25() {fmt.Println(unsafe.Sizeof(struct{}{})) // 0type structA struct {A int8     // 1 byteB struct{} // 0 byte}var a structAfmt.Println(unsafe.Sizeof(a)) // 2
}

这是为了防止对结构体最后一个零内存占用字段进行取地址操作时发生越界,而空结构体不放最后一个字段,不会额外填充。

当然,额外填充一字节也是会进行内存对齐的,unsafe.Alignof 返回变量的对齐要求:

func function26() {type structA struct {A int32    // 4 byteB struct{} // 0 byte}var a structAfmt.Println(unsafe.Sizeof(a), unsafe.Alignof(a)) // 8 4
}

JSON 序列化与反序列化

利用 encoding/json 包的 json.Marshaljson.Unmarshal 进行序列化和反序列化。

// JSON
func function28() {type Phone struct {Price int    `json:"price"`Name  string `json:"name"`}s := Phone{Price: 3888,Name:  "小米",}s1, _ := json.Marshal(s) // JSON 序列化fmt.Printf("%s\n", s1)   // {"price":3888,"name":"小米"}var a Phone_ = json.Unmarshal(s1, &a) // JSON 反序列化fmt.Println(a)             // {3888 小米}
}

上述序列化后,字段变为了 tag 定义的名称 pricename


方法和接收者

Go 允许为特定的变量设置专用的函数,这个专用的函数被称为方法(method)。通过方法接收者(receiver)来绑定方法和对象,接收者类似于 this、self。

方法声明

func (接收者 接收者类型) 方法名(参数) (返回值) {方法体
}
  • 建议接收者类型名称为首字母小写

  • 接收者类型:值接收者、指针接收者

    • 函数传参都是值拷贝,实参体积较大或函数内部需要修改实参,需要传递实参地址(指针)
    • 保持一致性。一个类型的某个方法使用了指针接收者,那么该类型其他方法应该保持一致
  • 通过结构体嵌套进行组合,实现面向对象的继承

  • Go 的语法糖 . 运算符,如果是指针,则会自动获取变量的地址

Go 通过内嵌其他结构体进行组合,每个被嵌入的结构体均会为其提供一些方法。当进行方法调用,会先查找当前结构体中是否声明了该方法,没有则依此去内嵌字段的方法中查找。

type Course struct {Name  stringScore int8
}// 值接收者
func (c Course) getName() string {return c.Name
}// 指针接收者
func (c *Course) setScore(score int8) {c.Score = score
}type Math struct {People int8Course
}func function30() {m := Math{People: 36,Course: Course{Name:  "math",Score: 100,},}fmt.Println(m.Course.Name, m.Score) // math 100m.setScore(120)fmt.Println(m.Course.getName(), m.Course.Score) // math 120
}

通过类型定义,声明一个新的类型,再为其声明方法。

  • 不支持为其他包的类型声明方法
  • 不支持为接口类型和基于指针定义的类型定义方法
type MyBool boolfunc (m MyBool) SayType() {fmt.Printf("%T\n", m)
}//type PtrMyBool *MyBool
//func (p PtrMyBool) SayType()  {}  // *MyBool' is a pointer typefunc function31() {var a MyBoola.SayType() // main.MyBool
}

补充

Go 中根据首字母的大小写确定访问权限,无论是方法名、常量、变量名还是结构体的名称。

  • 首字母大写,则可以被其他的包访问
  • 首字母小写,则只能在本包中使用

可以简单的理解:首字母大写是公有的,首字母小写是私有的。

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

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

相关文章

Go 命令行解析 flag 包之快速上手

本篇文章是 Go 标准库 flag 包的快速上手篇。 概述 开发一个命令行工具&#xff0c;视复杂程度&#xff0c;一般要选择一个合适的命令行解析库&#xff0c;简单的需求用 Go 标准库 flag 就够了&#xff0c;flag 的使用非常简单。 当然&#xff0c;除了标准库 flag 外&#x…

Linux 网络流量相关工具

本文聚焦于网络流量的查看、端口占用查看。至于网络设备的管理和配置&#xff0c;因为太过复杂且不同发行版有较大差异&#xff0c;这里就不赘述&#xff0c;后面看情况再写。 需要注意的是&#xff0c;这里列出的每一个工具都有丰富的功能&#xff0c;流量/端口信息查看只是其…

使用vue_cli脚手架创建Vue项目(cmd和图形化方式)

使用vue_cli脚手架创建Vue项目&#xff08;cmd和图形化方式&#xff09; 创建项目(cmd方式) vue create vue_cli1.方向键选择manually select feature(手动选择方式创建)&#xff0c;回车 2.按空格键选择需要的组件&#xff1a;Babel、PWA、Router、Vuex、CSS&#xff0c;回…

Linux - 数据流重定向、管道符、环境变量配置文件的加载

概述 想了解Linux编程&#xff0c;shell脚本是绕不开的关键知识点&#xff0c;原计划写一个整篇来分享shell的来龙去脉&#xff0c;但知识点过于繁杂&#xff0c;先分享一下学习shell的准备工作&#xff0c;数据流重定向、管道符、环境变量配置文件的加载&#xff0c;有助于知…

Linux之安装配置CentOS 7

一、CentOS简介 CentOS&#xff08;Community Enterprise Operating System&#xff0c;中文意思是社区企业操作系统&#xff09;是Linux发行版之一&#xff0c;它是来自于Red Hat Enterprise Linux依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码&#xff0c…

YOLOv8改进 | Conv篇 | 结合Dual思想利用HetConv创新一种全新轻量化结构CSPHet(参数量下降70W)

一、本文介绍 本文给大家带来的改进机制是我结合Dual的思想利用HetConv提出一种全新的结构CSPHet,我们将其用于替换我们的C2f结构,可以将参数降低越75W,GFLOPs降低至6.6GFLOPs,同时本文结构为我独家创新,全网无第二份,非常适合用于发表论文,该结构非常灵活,利用Dual卷…

CSS探索浏览器兼容性

学习如何探索浏览器的兼容性对于编写跨浏览器兼容的CSS代码非常重要。以下是一些学习CSS兼容性的方法&#xff1a; MDN文档&#xff1a;Mozilla开发者网络&#xff08;MDN&#xff09;提供了广泛而详细的CSS文档&#xff0c;其中包含有关CSS属性、选择器和功能的信息。在MDN上…

机器学习之pandas库学习

这里写目录标题 pandas介绍pandas核心数据结构SeriesDataFrameDataFrame的创建列访问列添加列删除行访问行添加行删除数据修改 pandas介绍 pandas是基于NumPy 的一种工具&#xff0c;该工具是为了解决数据分析任务而创建的。Pandas 纳入 了大量库和一些标准的数据模型&#xff…

谷歌seo服务商如何选择?

选择谷歌SEO服务商时&#xff0c;要考虑他们的经验、专业知识、成功案例、透明度、合规性、定制能力、时间线、客户支持、沟通以及是否能够建立长期合作关系。综合评估这些因素&#xff0c;确保找到一个可信赖的合作伙伴&#xff0c;能够帮助您提升网站在谷歌搜索中的表现&…

相机与镜头

一、相机视场 相机的视场角&#xff0c;也就是相机能够看到物像角度的最大值&#xff0c;视场角与焦距的关系为像高f*tan(fov/2)。由于相机的感光面是矩形&#xff0c;所以相机能够看到的区域也是矩形。探究相机的视场角&#xff0c;便于分析物面上那些区域属于相机盲区&#x…

STM正点mini-新建工程模板,GPIO及寄存器(介绍)

一.新建工程模板(基于固件库) 1.1库函数与寄存器的区别 这里的启动文件都是根据容量来进行区分的 对MDK而言即使include了&#xff0c;也不知道在哪里找头文件 STM32F10X_HD,USE_STDPERIPH_DRIVER 二.新建工程模板(基于寄存器) 上面的大部分配置与固件库的一样 具体可以看手…

带延迟的随机逼近方案(Stochastic approximation schemes):在网络和机器学习中的应用

1. 并行队列系统中的动态定价Dynamic pricing 1.1 系统的表述 一个含有并行队列的动态定价系统&#xff0c;该系统中对于每个队列有一个入口收费(entry charge) &#xff0c;且系统运行的目标是保持队列长度接近于某个理想的配置。 这里是这个系统的几个关键假设&#xff1a;…

redis-4 搭建redis集群

1.为什么需要redis集群&#xff1f; Redis 集群提供了高可用性、横向扩展和数据分片等功能&#xff0c;使得 Redis 能够应对大规模的数据存储和高并发访问的需求。以下是一些需要使用 Redis 集群的常见情况&#xff1a; 高可用性&#xff1a;通过在多个节点之间进行数据复制和…

计算机网络——TCP协议

&#x1f4a1;TCP的可靠不在于它是否可以把数据100%传输过去&#xff0c;而是 1.发送方发去数据后&#xff0c;可以知道接收方是否收到数据&#xff1b;2.如果接收方没收到&#xff0c;可以有补救手段&#xff1b; 图1.TCP组成图 TCP的可靠性是付出代价的&#xff0c;即传输效率…

苹果提审被拒反馈崩溃日志.text | iOS 审核被拒crashLog

iOS审核人员拒绝后每个截图&#xff0c;只给了几个text文件&#xff0c;这种情况就是审核的时候运行你的代码&#xff0c;崩溃了。 仅仅看text文件&#xff0c;是看不出所以然来的&#xff0c;所以我们要将日志转换成.crash格式 1.将.text文件下载下来&#xff0c;将 .text手动…

【Linux】进程间通信概念 | 匿名管道

文章目录 一、什么是进程间通信进程间通信的概念进程间通信的目的进程间通信的分类进程间通信的本质 二、什么是管道三、匿名管道匿名管道的原理✨站在内核角度理解管道✨站在文件描述符角度理解管道 pipe系统调用fork后在父子进程间使用管道通信代码实现 匿名管道的读写规则管…

stable diffusion学习笔记——文生图(一)

模型设置 基本模型 基本模型也就是常说的checkpoint&#xff08;大模型&#xff09;&#xff0c;基本模型决定了生成图片的主体风格。 如上图所示&#xff0c;基本模型的后缀为.safetensors。需要存放在特定的文件夹下。 如果用的是启动器&#xff0c;可以在启动器内直接下载。…

GPT-SoVITS 本地搭建踩坑

GPT-SoVITS 本地搭建踩坑 前言搭建下载解压VSCode打开安装依赖包修改内容1.重新安装版本2.修改文件内容 运行总结 前言 传言GPT-SoVITS作为当前与BertVits2.3并列的TTS大模型&#xff0c;于是本地搭了一个&#xff0c;简单说一下坑。 搭建 下载 到GitHub点击此处下载 http…

在JavaScript中获取当前时间yyyymmddhhmmss的六种实现方式

在编写JavaScript代码时&#xff0c;遇到需要获取当前日期和时间并将其格式化为 yyyymmddhhmmss 字符串的情况。可以使用本文中介绍的几种实现方式中的任意一种。 方法一&#xff1a;使用Date对象 使用 Date 对象来获取当前日期和时间。 示例代码&#xff1a; const now new D…

NC开发客户端(前端)连接启动失败can‘t connect to server, please wait

效果图 解决方法 IP地址和端口要对应 1-IP地址中间启动&#xff0c;肯定是这个127.0.0.1 2-端口号&#xff0c;要对应中间件启动在控制台输出的端口 或者是在home目录-》bin-》sysConfig.bat这里面的服务器&#xff0c; 里面可以看到对应启动ip地址和端口