唤醒手腕 2023年 B 站课程 Golang 语言详细教程笔记(更新中)

0001、1000集GO语言Flag毒誓

唤醒手腕UP猪Pig目标花费1000集进行讲解Go语言视频学习教程(有趣的灵魂,适合小白,不适合巨佬),从2023年3月19日开始,将会一直每天更新,准备在2024年5月1日之前更新完1000集Golang课程,更新不完直播吃完一整只烤卤猪(80斤)全盛晚饭。

最新2023年GoLang视频课程:目标花费1000集进行讲解Go语言视频学习教程(更新中)注入灵魂般的有趣,适合小白,不适合巨佬

0002、Golang编程语言历史

什么是谷歌工程师 20 % 时间?

谷歌工程师 20 % 时间 工作方式,允许工程师拿出 20 % 的时间来研究自己喜欢的项目。

在这里插入图片描述

语音服务 Google Now、谷歌新闻 Google News、谷歌地图 Google Map 上的交通信息等,全都是 20 % 时间的产物。Go 语言最开始也是 20 % 时间的产物。

Go 语言 3 位创始人是谁?

Robert Griesemer(罗伯特 · 格利茨默)Rob Pike(罗伯 · 派克)Ken Thompson(肯 · 汤普森)

Robert Griesemer:在开发 Go 之前是 Google V8、Chubby 和 HotSpot JVM 的主要贡献者。

Rob Pike:曾是贝尔实验室(Bell Labs)的 Unix 团队,和 Plan 9 操作系统计划的成员。他与 Thompson 共事多年,并共创出广泛使用的 UTF-8 字元编码。

Ken Thompson:主要是 B 语言、C 语言的作者、Unix 之父。1983 年图灵奖(Turing Award)和 1998 年美国国家技术奖(National Medal of Technology)得主。他和 Dennis Ritchie 是 Unix 的原创者。

在这里插入图片描述
为什么 Go 语言 叫做 Go 语言?

这是一封由 Rob Pike 在 2007 年 9 月 25 号,星期二,下午 3:12 回复给 Robert Griesemer、Ken Thompson 的有关编程语言讨论主题的邮件,邮件正文大意为:在开车回家的路上我得到了些灵感。给这门编程语言取名为 go,它很简短,易书写。工具类可以命名为:goc、 gol、goa。交互式的调试工具也可以直接命名为 go 。语言文件后缀名为 .go 等等。

这就是 Go 语言名字的来源,自此之后 Robert、Rob 和 Ken 三个人开始在 Google 内部进行了研发,一直到了 2009 年,Go 正式开源了,Go 项目团队将 2009 年 11 月 10 日,即该语言正式对外开源的日字作为其官方生日。源代码最初托管在 http://code.google.com 上,之后几年才逐步的迁移到 GitHub 上。

Go 语言 LOGO 是什么?

在这里插入图片描述

Go 语言的 logo 是 Rob Pike 的妻子 Renee French 设计的,她是一位才华横溢的插画家。

某梗 Golang Logo 灵感也来自于 《海贼王》

在这里插入图片描述

GO 语言 / C 语言 / Python 比较

Go 语言以其近 C 的执行性能和近解析型语言的开发效率,以及近乎于完美的编译速度,已经风靡全球。很多人将 Go 语言称为 21 世纪的 C 语言,因为 Go 不仅拥有 C 的简洁和性能,而且针对多处理器系统应用程序的编程进行了优化,很好的提供了 21 世纪互联网环境下服务端开发的各种实用特性。

在这里插入图片描述

0003、下载安装GO语言环境

谷歌公司 Golang 官方网站:https://go.dev/

在这里插入图片描述

.dev 域名主要是为开发者设计的,要求强制使用 HTTPS 来阻止广告恶意程序和 ISP 植入的跟踪代码。

特别注意:官方网站首次访问会比较慢,要耐心等一段时间等浏览器加载完毕。

中国地区 Golang 官网:https://golang.google.cn/

.CN 域名是中国国家顶级域名,是以 .cn 为后缀的域名,包括在 .CN 下直接注册的二级域名和在 .CN 二级域下注册的三级域名。

Java : JDK java develop kits
Python:python 解析器(cpython)

Golang 环境包下载(详细的安装教程 B 站有讲解)

下载链接:https://golang.google.cn/dl/

在这里插入图片描述
Go语言环境包目录结构
在这里插入图片描述
配置环境变量

在这里插入图片描述
补充 path 环境变量:%GOROOT%\bin

Windows操作系统中的PATH环境变量(Path Environment Variable)是一个非常重要的系统环境变量,在系统中起着非常重要的作用。

path 环境变量作用

查找可执行文件: PATH环境变量指定了一组目录的路径,操作系统会在这些路径中查找可执行文件(例如.exe、.bat、.cmd等),因此,当您在命令提示符或运行对话框中输入一个命令时,操作系统会按照PATH中的顺序搜索这些目录,以找到并执行相应的可执行文件。这使得您可以在任何目录下运行系统中已安装的可执行文件,而不必提供完整的路径。

便于运行脚本和命令: 如果您编写了自定义的批处理文件(.bat或.cmd)或脚本文件,可以将这些文件所在的目录添加到PATH中,这样您可以从任何位置运行它们,而不必在命令行中输入完整路径。

简化开发环境配置: 对于开发人员来说,PATH环境变量对于配置开发工具和编程环境非常重要。将编程语言的解释器、编译器、开发工具和相关的库文件所在的目录添加到PATH中,可以使开发过程更加顺利,无需每次都手动指定路径。

系统资源管理: 某些系统和应用程序需要访问特定的工具或资源文件,这些文件可能位于不同的目录中。通过使用PATH环境变量,可以简化对这些资源的管理和访问。

注意:编辑PATH环境变量时要小心,不要删除现有的重要路径,以免影响系统或应用程序的正常运行。

0004、编写HelloWorld程序

合格的程序员脱发皆由 Helloworld 开始 - - - 唤醒手腕

package mainimport "fmt"func main() {fmt.Println("Hello, 世界")
}

在Go语言中,go rungo build是两个常用的命令,它们用于不同的目的,并且在开发过程中有不同的用途。以下是它们的主要区别:

go run

进行对你写的程序代码进行编译操作,在编译后立即执行程序,生成一个临时文件,并没有可执行文件生成。

  • go run用于直接运行Go源代码文件,而不需要显式地生成可执行文件。
  • 当您使用go run命令时,它会编译您的代码并立即执行生成的可执行文件,然后输出程序的标准输出(如果有的话)。
  • 这在开发和测试阶段非常方便,因为它允许您快速查看和调试代码的输出,而无需手动编译并运行可执行文件。

示例用法

go run main.go

go build

  • go build用于编译Go源代码文件,并生成可执行文件,该可执行文件可以在需要时运行。
  • 当您使用go build命令时,它会将Go源代码编译成一个可执行文件(默认情况下与源代码文件名相同),该可执行文件位于当前目录。
  • 这适用于将Go应用程序部署到生产环境或与其他工具集成,因为它生成了一个独立的可执行文件,您可以多次运行它而无需重新编译。

示例用法

go build -o myapp main.go

总之,go run主要用于快速开发和测试,而go build用于生成可执行文件,以便将Go应用程序部署到不同的环境中。在实际开发中,这两个命令通常会结合使用,先使用go run来验证代码,然后使用go build生成可执行文件以进行部署。

注意:使用 go build 生成了可执行文件,那么不论当前的环境有没有 go 开发语言环境,都可以执行该可执行文件。

0005、安装Goland开发者工具

JetBrains 公司并没有一个名为 “Goland” 的产品。然而,我认为你可能在提到 “GoLand”,这是 JetBrains 为 Go 编程语言开发的一款集成开发环境(IDE)。

GoLand 是一个专门为 Go 语言开发者设计的集成开发环境,它提供了一系列功能和工具,旨在提高 Go 语言开发的效率和质量。

安装 go 开发者工具

安装 go 开发者工具:goland vscode(微软)goland 下载官网:https://www.jetbrains.com

在这里插入图片描述

go env

go env 命令用于打印查看Go开发包的环境配置信息

go env

Go 环境配置信息

GOBIN		编译器和链接器的安装目录,存放可执行文件的目录的绝对路径。
GOROOT		Golang 安装目录。
GOPATH		Golang 工作目录。

GOROOTGOPATH 是与 Go 编程语言相关的两个重要环境变量。它们用于配置和管理 Go 开发环境。

GOROOT 环境变量

  • GOROOT 是指定 Go 语言安装目录的环境变量。它表示 Go 编译器和标准库的安装路径。
  • 在你安装 Go 语言时,你需要指定一个目录作为 Go 的根目录,这个目录通常包含了 Go 的可执行文件、标准库和其他必要文件。
  • 通常情况下,Go 会自动设置 GOROOT 环境变量,但你也可以手动设置它,以确保你的开发环境使用正确的 Go 安装目录。

GOPATH 环境变量

  • GOPATH 是 Go 语言工作区的根目录。它用于存储你的 Go 项目和相关的库。
  • 当你使用 go get 命令来下载和安装第三方库时,这些库将被存储在 GOPATH 下的特定目录结构中。
  • GOPATH 中通常包含三个主要子目录:
    • src:用于存放你的 Go 项目源代码。
    • pkg:用于存放编译后的包对象文件。
    • bin:用于存放可执行文件(例如,通过 go install 构建的可执行文件)。

需要注意的是,Go 1.11 版本引入了 Go Modules,这是一种更现代的依赖管理机制,允许开发者在不依赖于 GOPATH 的情况下管理项目依赖。在使用 Go Modules 的项目中,你不再需要设置 GOPATH,而是可以在项目目录中使用 go.modgo.sum 文件来管理依赖。

总之,GOROOTGOPATH 是 Go 开发环境中的两个重要概念,它们分别表示 Go 安装目录和工作区的根目录。但随着 Go 语言的发展,Go Modules 已经成为更常见和推荐的依赖管理方式,因此在新的项目中,你可能不需要设置 GOPATH

0006、安装vscode开发者工具

Vscode 官方网站:https://code.visualstudio.com/

在这里插入图片描述

上节课 Goland 开发者工具(x)

go: go.mod file not found in current directory or any parent directory; see ‘go help modules’

GO111MODULE 是 Go 1.11 引入的新版模块管理方式。GO111MODULE 环境变量用于开启或关闭 Go 语言中的模块支持,它有 off、on、auto 三个可选值,默认为 auto。

  • GO111MODULE=off
    无模块支持,go 会从 $GOPATH 文件夹和 vendor 目录中寻找依赖项。

  • GO111MODULE=on
    模块支持,go 忽略 $GOPATH 文件夹,只根据 go.mod 下载依赖。

  • GO111MODULE=auto
    在 $GOPATH/src 外层且根目录有 go.mod 文件时,开启模块支持;否者无模块支持。

go: no module declaration in go.mod. To specify the module path:
go mod edit -module=example.com/mod

0007、fmt.print打印函数

fmt 包实现了类似C语言 printf 和 scanf 的格式化 I/O。

go 内置包 - fmt 包:fmt.print

在这里插入图片描述

什么是格式化输出?简单说就是挖个坑,再拿东西去填(什么样的坑,就填什么东西)

Golang 占位符介绍

%v值的默认格式 variable
%ttrue 或 false bool
%b表示二进制 binary
%o表示八进制 octonary
%d表示十进制 decimal
%x表示为十六进制 使用 a-f hex
%X表示为十六进制 使用 A-F hex
%c表示值对应的 unicode 码值 code
%f表示浮点数(默认精度为 6)

0008、Go语言变量命名规则

变量名的首字母是:下划线 _ 、字母

变量名的非首字母部分是:下划线 _ 、字母、数字

例如:

_a、b1、a_

注意:理论上汉字也可以作为变量名称,但是不推荐使用汉字作为变量名,原因是你懂的。

package mainimport "fmt"func main() {var 蔡徐坤 = "鸡你太美"fmt.Printf("%v", 蔡徐坤)
}

Go语言 25个关键字

在这里插入图片描述

包相关: import、 package
声明相关: var、 const、 type、 struct、 interface、 func、 chan、 map、 go
循环相关: for、 range
条件判断相关: if、 else、 switch、 select、 case
中断或返回: return、 goto(嵌套 for 循环 goto 大法)、 fallthrough、 break、default、 continue
延迟执行: defer

Go 语言保留字

常量: true、false、iota(自动递增数字的常量定义)、nil(例如:python None、java null、c++ NULL)
整型:int、 int8 占1个字节、 int16 占2个字节、 int32 占4个字节、 int64 占8个字节
无符号整型:uint、 uint8、 uint16、 uint32、 uint64、 uintptr
浮点型:float32、 float64、 complex64、 complex128 
其他:bool、byte、 rune(unicode 字符问题)、string、 error
函数: make、len、cap、new、append、copy、close、delete、complex、real、imag、panic、 recover
int 		类型大小为 8 字节 和计算机系统保持一致
int8	 	类型大小为 1 字节
int16		类型大小为 2 字节
int32 		类型大小为 4 字节
int64 		类型大小为 8 字节
package mainimport "fmt"
import "unsafe"func main() {var i1 int = 0var i2 int8 = 0var i3 int16 = 0var i4 int32 = 0var i5 int64 = 0fmt.Println(unsafe.Sizeof(i1))fmt.Println(unsafe.Sizeof(i2))fmt.Println(unsafe.Sizeof(i3))fmt.Println(unsafe.Sizeof(i4))fmt.Println(unsafe.Sizeof(i5))
}

注意:unsafe.Sizeof() 只返回数据类型的大小,不管引用数据的大小,单位为 Byte

unsafe 是什么?

unsafe 库让 golang 可以像 C 语言一样操作计算机内存,但这并不是 golang 推荐使用的,能不用尽量不用,就像它的名字所表达的一样,它绕过了 golang 的内存安全原则,是不安全的,容易使你的程序出现莫名其妙的问题,不利于程序的扩展与维护。

查看计算机是几位的?

cmd > systeminfo系统类型:x64-based PC

0009、算数运算符和关系运算符

注意:如果你学过任何一门编程语言,都可以十倍速观看了解即可!

Go 算数运算符

var a = 1314
var b = 520
fmt.Println(a + b)
fmt.Println(a - b)
fmt.Println(a*b, a/b, a%b)a++
b++
fmt.Println(a)
fmt.Println(b)

C++ 随堂测试?

int a = 0;
a = a+++++a;
cout << a;
int a = 1
a = (a++)+(++a)*a+(++(++a))*((a++)++)+a;
cout << a;

Go 关系运算符

var a = 1314
var b = 520
fmt.Println(a<=b)
fmt.Println(a>=b)
fmt.Println(a==b)
fmt.Println(a!=b)

0010、逻辑运算符和短路特性

逻辑运算符

在这里插入图片描述

逻辑运算符表示
! 逻辑非运算符!条件表达式
逻辑或运算符条件表达式①
&& 逻辑与运算符条件表达式① && 条件表达式②

逻辑运算符短路特性

就是说,逻辑运算符 && 和 || 在执行时,如果前边的条件结果能够决定整个表达式的结果,那么就不会执行下一条语句。

比如 && ,前边的条件语句执行的结果为 false,那么后边的结果就不需要执行。因为后边的条件语句不论结果是什么,整个表达式的结果都为 false 值。

package mainimport "fmt"func main() {var a = 1var b = 0if a > 0 && a / b > 0 {fmt.Println("OK")}fmt.Println("end")
}

b == 0 因此假设代码执行到 && 运算符之后,那么代码会报错。

同理,在 || 语句中,假设前边的条件语句为 true,那么整个表达式的结果就为 true,而无需执行后面的条件语句。

package mainimport "fmt"func main() {var a = 1var b = 0if a < 0 || a / b > 0 {fmt.Println("OK")}fmt.Println("end")}

b = 0 因此假设代码执行到 && 运算符之后,那么代码会报错。

0011、计算机原码和反码和补码

二进制数表示

当前电子计算机技术全部采用的是二进制,因为它只使用 0、1 两个数字符号,非常简单方便,易于用电子方式实现。

1个字节表示 无符号的二进制数

1 => 0000 0001

1个字节表示 有符号的二进制数

二进制的最高位是符号位:0 表示正数 1 表示负数

+1 => 0000 0001
-1 => 1000 0001

int8 取值范围 -128 ~ 127

计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用 0 和 1 两个数字及其组合来表示任何数。进位规则是“逢 2 进 1”,数字 1 在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增。

其实还有一种很好理解的解释?

1.int8 占 1 个字节(byte) 也就是 8 个二进制位(bit)
2.每个二进制位可以存储 0 和 1 两个数 ,8 个二进制位就有 2 ^ 8 = 256种组合(可以存储 256 个数)
3.int8 为有符号,所以正数和负数将平分 256 个数。256 / 2 = 128
4.负数为 128 个数,最小值为- 128。  eg:1111 1111 -127、0000 0000 +0、1000 0000 -128	
5.正数为 128 个数,0 占一个数。	  eg:最大值为 +127	0111 1111	+127

原码 + 反码 + 补码

正数的原码 | 反码 | 补码都一样。

负数的反码 = 它的原码符号位不变,其他位取反。

1000 0001   (-1 原码)
1111 1110	(-1 反码)

另一种演示

*111 1111-
*000 0001=
*111 1110
+1    原码(0000 0001) 反码(0000 0001) 补码(0000 0001-1    原码(1000 0001) 反码(1111 1110) 补码(1111 1111)  负数的补码 = 它的反码 + 1

0 的 反码 和 补码 都是 0 important

作用:在计算机运算的时,都是以补码的方式来运算。

加法运算:3 + 2
减法运算:3 - 2 = 1 + (-2)

补码运算

因为补码是可以连同符号位一起运算,所以运算法则等同于无符号二进制运算:

 00000011    3 二进制补码表示00000010    2 二进制补码表示00000101    转换成 10 进制是 5  结果正确!

3 + (-2)

 00000011    +3 二进制补码表示10000010    -2 二进制原码表示11111101	 -2 二进制反码表示11111110    -2 二进制补码表示00000011    +3 二进制补码表示 11111110    -2 二进制补码表示
100000001    转换成 10 进制是 1  结果正确!

特别注意:补码的运算是连同符号位一起运算的。

在计算机中各种运算都是 CPU 来完成的,计算机的 CPU 是不会算减法的。CPU在算术运算上只能做加法和移位和取反运算。

在这里插入图片描述

过 13 个小时	 =>	过 1 个小时
倒退 1 个小时 => 过 11 个小时

十进制演示

0 1 (binary 二进制)

0 1 2 3 4 5 6 7 8 9 (decimal 十进制)

(+2) + (-2) = 0

2 - 2

(-2) 反码 => (-7)	eg. 9 - 2 = 7
(-7) + 1 = (-8)
(+2) + (-8) = 10 => 0

0012、位运算和位运算符

位运算?

现代计算机中所有的数据二进制的形式存储在设备中,位运算就是计算机对二进制的0和1进行操作。

位运算符

位运算符是将数值转换为二进制进行计算。我们无须手动将数值转换为二进制,只需对数值使用位运算符即可。

在这里插入图片描述

左移<<:左移一位,相当于原数乘2;左移n位,原数乘2^n
右移>>:右移一位,相当于原数除2;右移n位,原数除2^n

注意:假如有余数,余数会被抹掉。除操作的余数是忽略的,得到的结果是商。

var a = 60 // 60 = 0011 1100
var b = 13 // 13 = 0000 1101
var c = 0
c = a & b
fmt.Printf("c的十进制值为 %d\n", c) // 12
fmt.Printf("c的二进制值为 %b\n", c) // 1100
c = a | b
fmt.Printf("c的十进制值为 %d\n", c) // 61
fmt.Printf("c的二进制值为 %b\n", c) // 111101
c = a ^ b
fmt.Printf("c的十进制值为 %d\n", c) // 49
fmt.Printf("c的二进制值为 %b\n", c) // 110001
c = a << 2
fmt.Printf("c的十进制值为 %d\n", c) // 240
fmt.Printf("c的二进制值为 %b\n", c) // 15
c = a >> 2
fmt.Printf("c的十进制值为 %d\n", c) // 15
fmt.Printf("c的二进制值为 %b\n", c) // 1111

判断奇偶

只要根据最未位是 0 还是 1 来决定,为 0 就是偶数,为 1 就是奇数。

因此可以用 if ((a & 1) == 0) 代替 if (a % 2 == 0) 来判断 a 是不是偶数。

**** ***1  奇数
0000 0001  0000 0001  1
0000 0000  0

0013、指针运算符和位运算符

取地址运算符

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

package mainimport "fmt"func main() {var a int = 10fmt.Println(a)fmt.Printf("变量的地址: %X \n", &a)a = a + 1fmt.Println(a)fmt.Printf("变量的地址: %X \n", &a)
}

输出结果是变量 a 所在的内存地址。

指针是什么?

一个指针变量就是一个值的内存地址。那么就可以通过这个变量的地址(指针)去访问它。

在使用指针前你需要声明指针。

指针的声明

var name *var-type

var-type 为指针类型(指针类型就是指针所指向了一个什么类型的变量),name 为指针名,* 号用于指定变量是一个指针。

Go 语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等。

在这里插入图片描述

package mainimport "fmt"func main() {var a int = 10var b *int = &afmt.Printf("变量a的值:%v, 变量a的内存地址:%v   \n", a, &a)fmt.Printf("指针b的值:%v, 指针b的内存地址:%v   \n", b, &b)fmt.Printf("指针b读取变量a的值:%v", *b)
}

指针使用流程

1. 定义指针变量。
2. 指针变量赋值。
3. 访问指针变量中地址指向的值:在指针前面加上 * 号来获取指针指向的地址块的内容。

补充:运算符优先级

在这里插入图片描述

0014、Go语言电脑关机整蛊程序

打开记事本案例

package mainimport ("fmt""os/exec"
)func main() {var cmd = exec.Command("notepad")err := cmd.Run()if err != nil {fmt.Printf("error is : %s", err)} else {fmt.Println("exec successfully")}return
}

os/exec 包是 Golang 语言中用于调用执行外部命令的库。

exec.Command

exec.Command() 函数用于使用给定的参数来执行名为 name 的程序,返回结果是一个 Cmd 指针对象。

自动关机

package mainimport ("fmt""os/exec"
)func main() {var arg = []string{"-s", "-t", "120"}var cmd = exec.Command("shutdown", arg...)var err = cmd.Run()if err != nil {fmt.Println("error tips:", err)}return
}

0015、整蛊程序血淋淋教训

在1000集 课程中,穿插相关的有趣案例等等。基础知识 / 数据库 (redis ,mysql, mongodb)/ Linux 云服务器 / beego / go 云原生与微服务 等等(1000集内容会非常丰富)

假如我明天还能继续录的话,我会继续录,但是我的几个朋友,正在拿刀来的路上。呜呜呜~~~~

Comand 常用函数

Run():Run starts the specified command and waits for it to complete. 阻塞

start():Start starts the specified command but does not wait for it to complete.

CombinedOutput():CombinedOutput runs the command and returns its combined standard.

0016、Go语言var声明变量

Go语言是静态类型语言,因此变量(variable)是有明确类型的,编译器也会检查变量类型的正确性。

在数学概念中,变量表示没有固定值且可改变的数。高中函数中的自变量 x 不是固定的。但从计算机系统实现角度来看,变量是一段或多段用来存储数据的内存。

使用 var 关键字:声明变量 variable var

var name type = 表达式

var 声明变量的关键字 name 变量名 type 变量类型

需要注意的是,Go语言和大部分其他编程语言不同,在声明变量时,将变量类型放在变量名称后面。

int a = 1;  						 c++
String name = "hello";  			 java
String name = new String("hello");   java

go 指针类型

var a, b *int

Go语言在声明变量时,自动对变量对应的内存区域进行初始化操作。每个变量会初始化其类型的默认值,例如:

  • 整型和浮点型变量的默认值为 0 和 0.0。
  • 字符串变量的默认值为空字符串。
  • 布尔型变量默认为 false。
  • 切片、函数、指针变量的默认为 nil。

浮点数初始化关键点

由于Go语言和C语言一样,编译器会尽量提高精确度,以避免计算中的精度损失。所以这里如果不指定 f 变量的类型,Go语言编译器会将 f 类型推导为 float64,我们这里不需要 float64 的精度,所以需要强制指定类型为 float32。

reflect 内置包 TypeOf()

reflect - Go 反射机制

标准格式

Go语言 声明变量 标准格式:

var 变量名 变量类型 = 表达式

变量声明以关键字 var 开头,后置变量类型,行尾无须分号。为什么不同语言会这样?这就好比国内的车驾驶员在车的左侧,国外的车型驾驶员在车的右侧。

批量格式 / 组合格式

觉得每行都用 var 声明变量比较烦琐?没关系,还有一种为懒人提供的定义变量的方法:

var (a intb stringc []float32b struct {x int}
)

使用关键字 var 和括号,可以将一组变量定义组合起来声明。

简短格式

简短模式(short variable declaration)SVD - 变量定义和初始化语法。

名字 := 表达式

注意点:1. 需要初始化 2. 不提供数据类型 3. 只能用在函数内部

和 var 形式声明语句一样,简短变量声明语句。同时也可以用来声明和初始化一组变量:

i, j := 0, 1
package mainimport "fmt"func main(){var a, b intb = 1fmt.Println("a = ", a, ", b = ", b)var c int = 1fmt.Println("c = ", c)d := 1fmt.Println("d = ", d)x, y, z, _ := 1, 2, 3, 4;fmt.Printf("x = %d, y = %d, z = %d \n", x, y, z)
}

因为简洁和灵活的特点,简短变量声明被广泛用于大部分的 局部变量 的声明和初始化。var 形式的声明语句往往是用于需要显式指定变量类型地方,或者因为变量稍后会被重新赋值而初始值无关紧要的地方。

0017、Go语言匿名变量

匿名变量不占用命名空间,不会分配内存。匿名变量与匿名变量之间也不会因为多次声明而无法使用。

注意:匿名变量在编译阶段完成的事情,并不会在运行时去实际赋值,所以不应该叫做变量。

匿名变量作用

package mainimport "fmt"func VendingMachine() (water, noodles, sweet string) {return "元气森林", "康师傅泡面", "口香糖"
}func main() {var water, noodle, sweet string = VendingMachine()fmt.Println(water, noodle, sweet)
}
1、Go语言支持返回多个值(多重返回)
2、如果只想获取某个值,不用像其他语言声明所有变量(匿名变量)

匿名变量的特点是一个下画线 _,本身就是一个特殊的标识符,被称为空白标识符。它可以像其他标识符那样用于变量的声明或赋值(任何类型都可以赋值给它),但任何赋给这个标识符的值都将被抛弃,因此这些值不能在后续的代码中使用,也不可以使用这个标识符作为变量对其它变量进行赋值或运算。使用匿名变量时,只需要在变量声明的地方使用下画线替换即可。

在编码过程中,可能会遇到没有名称的变量、类型或方法。虽然这不是必须的,但有时候这样做可以极大地增强代码的灵活性,这些变量被统称为匿名变量。

0018、Go 简单数据类型互相转换

go 在不同类型的变量之间赋值时,需要显式转换。简单理解,就是 go 的数据类型不能自动转换

Go 数据类型

  • 基础类型:整数、浮点数、复数、布尔值、字符串、常量
  • 聚合类型:数组、结构体 struct
  • 引用类型:指针、切片 slice、映射 map、函数、通道
  • 接口类型:接口

变量转换方式

底层相同结构类型的变量转换方式

T(v) 将值 v 转换为类型 T; int(v)  float64(v)

注意:采用这种方式转换 两个变量的类型在底层具有相同数据结构类型

var a byte = 'W' // 字符类型   GO: 字符类型(byte 类型,rune 类型)
b := string(a)   // 转换为字符串类型
var a int8 = 10  // int8 类型
b := float32(a)  // 转换成浮点数类型

引用:字符串转数字 Go语言strconv 库的 Atoi

高精度转低精度内存溢出情况

package mainimport "fmt"func main() {var a int16 = 520var b, c, d int8b = int8(a) + 127 // 【编译时通过】但是结果会溢出,c = int8(a) + 128 // 【编译不会通过】数据类型为int8,int8 的范围 -128 ~ 127d = int8(a)fmt.Println(a)fmt.Println(b)fmt.Println(c)fmt.Println(d)
}

520 int16 2 个字节 16 位 有一位是符号位 15 位是数据位

在这里插入图片描述

int8 1 个字节 8 位 有一位是符号位 7 位是数据位

int8(520) 1 个字节 8 位

在这里插入图片描述

0019、字符串和基本数据类型转换

在实际开发中我们往往需要对一些常用的数据类型进行转换,如 stringintint64float 等数据类型之间的转换, Go 语言中的 strconv 包为我们提供了字符串和基本数据类型之间的转换功能。

a = Type(b)  

Type 要显式转换的类型。b 要转换的变量。两个变量的类型在底层需要具有相同(相似)的数据结构。比如:int 和 float64 byte 和 string(strconv string convert)

整数和字符串之前转换用到的两个函数

strconv.Itoa(): 整型转字符串

func Itoa(i int) string

Itoa() 函数用于将 int 类型数据转换为对应的字符串类型

func main() {num := 100str := strconv.Itoa(num)fmt.Printf("类型:%T 值:%v  \n", str, str)
}

strconv.Atoi(): 字符串转整型

func Atoi(s string) (i int, err error)

Atoi() 函数用于将字符串类型的整数转换为 int 类型

Atoi() 函数有两个返回值,i 为转换成功的整型,err 在转换成功是为空转换失败时为相应的错误信息。

ascii to integer

scanf、scan、scanln / Printf Print Println(c++ cin >> a / scanf)

上节课 Itoa() / Atoi() 整型 和 字符串

0020、strconv.Parse系列函数

strconv 内置包 Parse系列函数:解决 字符转非整型(也可以转整形)的数值。

parse 单词意思:vt. 从语法上描述或分析(词句等)

Parse 系列函数用于将字符串转换为指定类型的值,其中包括 ParseBool()ParseFloat()ParseInt()ParseUint()ParseComplex

strconv.ParseBool()

ParseBool() 函数用于将字符串转换为 bool 类型的值,它只能接受 1 、 0 、 t 、 f 、 T 、 F 、 true 、 false 、 True 、 False 、 TRUE 、 FALSE ,其它的值均返回错误。函数签名如下:

func ParseBool(str string) (value bool, err error)
package mainimport ("fmt""strconv"
)func main() {var str string = "true"res, err := strconv.ParseBool(str)if err != nil {fmt.Println(err)} else {fmt.Println(res)}
}

strconv.ParseInt() 类似:Atoi()

ParseInt() 函数用于返回字符串表示的整数值(可以包含正负号),函数签名:

func ParseInt(s string, base int, bitSize int) (i int64, err error)

参数说明:

base 指定进制,取值范围是 2 到 36。如果 base 为 0,则会从字符串前置判断,“0x”是 16 进制,“0”是 8 进制,否则是 10 进制。

bitSize 指定类型,0、8、16、32、64 分别代表 int 、 int8 、 int16 、 int32 、 int64 。

package mainimport ("fmt""strconv"
)func main() {var str string = "-100"res, err := strconv.ParseInt(str, 10, 8)if err != nil {fmt.Println(err)} else {fmt.Println(res)}
}

strconv.ParseUint()

ParseUint() 函数的功能类似于 ParseInt() 函数

区别:ParseUint() 函数不接受正负号,用于无符号整型。函数签名:

func ParseUint(s string, base int, bitSize int) (n uint64, err error)base 指定进制,取值范围是 236。如果 base 为 0,则会从字符串前置判断,“0x”是 16 进制,“0”是 8 进制,否则是 10 进制。bitSize 指定类型,08163264 分别代表 intint8int16int32int64
package mainimport ("fmt""strconv"
)func main() {var str string = "100"res, err := strconv.ParseuInt(str, 10, 8)if err != nil {fmt.Println(err)} else {fmt.Println(res)}
}

strconv.ParseFloat()

ParseFloat() 函数用于将一个表示浮点数的字符串转换为 float 类型.函数签名:

func ParseFloat(s string, bitSize int) (f float64, err error)

参数说明:

如果 s 合乎语法规则,函数会返回最为接近 s 表示值的一个浮点数(使用IEEE754无偏舍入)。
bitSize 指定类型,32 表示 float32,64 表示 float64;

package mainimport ("fmt""strconv"
)func main() {var str string = "520.1314"res, err := strconv.ParseFloat(str, 64)if err != nil {fmt.Println(err)} else {fmt.Println(res)}
}

strconv.ParseComplex()

ParseComplex() 函数用于将一个表示复数的字符串转换为 complex 类型。函数签名:

func ParseComplex(s string, bitSize int) (complex128, error)
package mainimport ("fmt""strconv"
)func main() {var str string = "100+1i"	// 注意:字符串表达式不能带有空格res, err := strconv.ParseComplex(str, 64)if err != nil {fmt.Println(err)} else {fmt.Println(res)}
}

常见 error

// ErrRange indicates that a value is out of range for the target type.
var ErrRange = errors.New("value out of range")// ErrSyntax indicates that a value does not have the right syntax for the target type.
var ErrSyntax = errors.New("invalid syntax")

IEEE754 标准

IEEE754标准提供了如何在计算机内存中,以二进制的方式存储十进制浮点数的具体标准。IEEE754标准发布于1985年. 包括 javascript, Java, C在内的许多编程语言在实现浮点数时, 都遵循IEEE754标准。

parse 系列:字符串 转 给定类型数据(bool / int64 / uint64 / float64 / complex128)

0021、strconv.Format系列函数

Format 系列函数实现了将给定类型数据格式化为字符串类型的功能,其中包括 FormatBool()FormatInt()FormatUint()FormatFloat()FormatComplex

fmt.Printf:print format

fmt.scanf:scan format

FormatBool()

FormatBool() 函数可以一个 bool 类型的值转换为对应的字符串类型。函数签名:

func FormatBool(b bool) string
func main() {num := truestr := strconv.FormatBool(num)fmt.Printf("type:%T,value:%v\n ", str, str)
}

FormatInt()

FormatInt() 函数用于将整型数据转换成指定进制并以字符串的形式返回。函数签名:

func FormatInt(i int64, base int) string

其中,参数 i 必须是 int64 类型,参数 base 必须在 2 到 36 之间,返回结果中会使用小写母“a”到“z”表示大于 10 的数字。

func main() {var num int64 = 100str := strconv.FormatInt(num, 16)fmt.Printf("type:%T,value:%v\n ", str, str)
}

base 为什么是 2 ~ 36 之间?

0123456789 10个数字 + abcdefghijklmnopqrstuvwxyz 26个字母

FormatUint()

FormatUint() 函数与 FormatInt() 函数的功能类似,但是参数 i 必须是无符号的 uint64 类型,函数签名如下。

FormatUint() 函数用于将无符号整型数据转换成指定进制并以字符串的形式返回。函数签名:

func FormatUint(i uint64, base int) string
func main() {var num uint64 = 110str := strconv.FormatUint(num, 16)fmt.Printf("type:%T,value:%v\n", str, str)
}

FormatFloat()

FormatFloat() 函数用于将 float64 浮点数转换为字符串类型。函数签名:

func FormatFloat(f float64, fmt byte, prec, bitSize int) string

bitSize 表示参数 f 的来源类型(32 表示 float32、64 表示 float64)

fmt 表示格式 科学计数法

'b' (-ddddp±ddd, a binary exponent),
'e' (-d.dddde±dd, a decimal exponent),
'E' (-d.ddddE±dd, a decimal exponent),
'f' (-ddd.dddd, no exponent),
'g' ('e' for large exponents, 'f' otherwise),  
'G' ('E' for large exponents, 'f' otherwise),
'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or
'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent).

prec 控制精度

The special precision -1 uses the smallest number of digits

在 Go 编程中,用来表示小数的有两种类型:

float32(单精度类型,占据 4 个字节 byte,32 个二进制位 bit)

在这里插入图片描述

float64(双精度类型,占据 8 个字节 byte,64 个二进制位 bit)

在这里插入图片描述

exponent:指数 fraction:小数

func main() {var num float64 = 3.1415926str := strconv.FormatFloat(num, 'E', -1, 64)fmt.Printf("type:%T,value:%v\n", str, str)// type:string,value:3.1415926E+00
}

FormatComplex()

略~~~

0022、fmt.Scan扫描函数

控制台输出:fmt.Print fmt.Printf fmt.Println

fmt包下的三个扫描函数,类似于java中是Scanner一样,在Go语言中使用&变量名称来进行获值。

cin >> a   c++
a = input("a = ")   matlab  / python 
函数参数使用细节返回值
Scanf格式化字符串, 内存空间地址(可传多个)传入的值必须满足格式的要求成功的值数量, 失败的原因
Scan内存空间地址(可传多个)识别换行符为空格成功的值数量, 失败的原因
Scanln内存空间地址(可传多个)识别换行符为完成成功的值数量, 失败的原因

在这里插入图片描述

fmt.Scan

输入:读取以空白符分割的值返回到地址中进行修改,换行视为空白符。

返回值:错误处理,返回值中有一个int类型的值是返回正确的数量,有一个err是错误的原因

package mainimport "fmt"func main() {var (name  stringage   intmoney float64)n, err := fmt.Scan(&name, &age, &money)if err != nil {fmt.Println("错误:", err, "成功的值数量:", n)} else {fmt.Println(n, name, age, money)}
}
wrist 
21
520.1314

注意:当出现输入错误则之后全部错误

Scan scans text read from standard input, storing successive space-separated values into successive arguments. Newlines count as space. It returns the number of items successfully scanned. If that is less than the number of arguments, err will report why.

扫描扫描从标准输入读取的文本,将连续的空格分隔值存储到连续的参数中。换行算作空格。它返回成功扫描的项目数。如果这小于参数的数量,err将报告原因。

fmt.Scanf

格式化读入,暗含强制类型转换。Scanf扫描从标准输入读取的文本,将空格分隔的连续值存储到由格式决定的连续参数中。

Scanf scans text read from standard input, storing successive space-separated values into successive arguments as determined by the format. It returns the number of items successfully scanned. If that is less than the number of arguments, err will report why. Newlines in the input must match newlines in the format. The one exception: the verb %c always scans the next rune in the
input, even if it is a space (or tab etc.) or newline.

Scanf 扫描从标准输入读取的文本,将连续的空格分隔值存储到由格式确定的连续参数中。它返回成功扫描的项目数。如果这小于参数的数量,则err将报告原因。输入中的换行符必须与格式中的换行符匹配。一个例外:动词%c总是扫描输入中的下一个符文,即使它是空格(或制表符等)或换行符。

package mainimport "fmt"func main() {var (name  stringage   intmoney float64)n, err := fmt.Scanf("%s %d %f", &name, &age, &money)if err != nil {fmt.Println("错误:", err, "成功的值数量:", n)} else {fmt.Println(n, name, age, money)}
}
n, err := fmt.Scanf("\nname=%s\nage=%d\nmoney=%f", &name, &age, &money)

注意:当出现输入错误则之后全部错误

案例用途

n, err := fmt.Scanf("name=%s & age=%d & money=%f", &name, &age, &money)
name=wristwaking & age=12 & money=200

fmt.Scanln

Scanln 类似 Scan,但它在遇到换行时才停止扫描。最后一个数据后面必须有换行或者到达结束位置。使用场景就是只要换行就结束。

返回错误和Scan一样。

Scanln is similar to Scan, but stops scanning at a newline and after the final item there must be a newline or EOF.

ScanIn类似于Scan,但在换行处停止扫描,并且在最后一项之后必须有换行符或EOF。

0023、Go语言变量作用域

作用域:已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。

Go语言中变量可以在 3 个地方声明:

  • 局部变量:函数内部声明 / 定义的变量叫局部变量,作用域仅限于函数内部。
  • 全局变量:函数外部声明 / 定义的变量叫全局变量,可以在整个包甚至外部包(导出)中使用。全局变量和局部变量的名称可以相同,但是函数内会优先使用局部变量。
  • 参数变量:在函数中,作为局部变量来使用。

局部变量 local variable

什么是局部变量?在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。

注意点:局部变量不是一直存在的,它只在定义它的函数被调用后存在,函数调用结束后这个局部变量就会被销毁。

package mainimport ("fmt"
)var age int = 20
var name string = "wrist"func test() {age := 10name := "waking"fmt.Println("age = ", age)fmt.Println("name = ", name)
}func main() {fmt.Println("age = ", age)fmt.Println("name = ", name)fmt.Println("-----")test()
}

全局变量 global variable

定义:函数外部定义的变量都属于全局变量。全局变量声明必须以 var 开头。
生效范围:当前 package 内。

注意:如果想要其他 package 访问,全局变量以大写开头。

utils > hello.go

package utilsvar hello string = "hello world"

utils > tool.go

package utilsimport ("fmt""time"
)var Watch string = time.DateTimefunc Hello() {fmt.Println(hello)
}

main.go

package mainimport "awesomeProject/utils"func main() {utils.Hello()
}

参数变量 parameter variable

定义:函数调用时传递的变量。
生效范围:函数范围。

在定义函数时函数名后面括号中的变量叫做形式参数(简称形参)。

特别重要:形式参数只在函数调用时才会生效,函数调用结束后就会被销毁,在函数未被调用时,函数的形参并不占用实际的存储单元,也没有实际值。

形式参数会作为函数的局部变量来使用。

package mainimport "fmt"var a int = 30func main() {var a int = 10var b int = 20var c int = 0fmt.Printf("main() 函数中 a = %d \n", a)fmt.Println("-----")c = sum(a, b)fmt.Println("-----")fmt.Printf("main() 函数中 c = %d \n", c)
}func sum(a, b int) int {fmt.Printf("sum() 函数中 a = %d \n", a)fmt.Printf("sum() 函数中 b = %d \n", b)return a + b
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【VUE复习·8】v-if;v-show高级

总览 1.v-if 与其变种 v-else-if&#xff1b;v-else 2.v-show 3.v-if 与 v-show 的区别和应用场景 一、v-if 这样用&#xff08;使用 data 或 函数 来驱动它&#xff09; 1.v-if v-if 的用法很简单&#xff0c;它判断的是后面语句的 boolean 值&#xff0c;用来控制 DOM 元…

开源对手模拟工具:Network Flight Simulator

Network Flight Simulator 是一款轻量级实用程序&#xff0c;可生成恶意网络流量并帮助安全团队评估安全控制和网络可见性。 该工具执行测试来模拟 DNS 隧道、DGA 流量、对已知活动 C2 目的地的请求以及其他可疑流量模式。 安全行业内关于全面产品&#xff08;例如 EDR、SI…

外汇天眼:外汇交易一周最佳外汇交易日!

外汇市场运行24小时&#xff0c;但并非每时每刻都适合交易。本文将为您介绍一周中最佳外汇交易日&#xff0c;以及哪些时间段最适合参与外汇交易。 首先&#xff0c;值得注意的是伦敦时段通常是外汇市场最繁忙的时段。然而&#xff0c;即便如此&#xff0c;一周中仍有特定的日…

蓝桥杯每日一题2023.9.27

4408. 李白打酒加强版 - AcWing题库 题目描述 题目分析 对于这题我们发现有三个变量&#xff0c;店&#xff0c;花&#xff0c;酒的数量&#xff0c;对于这种范围我们使用DP来进行分析。 dp[i][j][k]我们表示有i个店&#xff0c;j朵花&#xff0c;k单位酒的集合&#xff0c…

B树和B+树的介绍和对比,以及MySQL为何选择B+树

在计算机科学中&#xff0c;B树和B树是常用的数据结构&#xff0c;用于在大规模数据集上进行高效的插入、删除和查找操作。它们在数据库管理系统、文件系统等许多实际应用中发挥着重要作用。本文将深入介绍B树和B树的结构特点、实际应用方面以及它们的优缺点&#xff0c;并最后…

Unity3d中Scene场景2D模式下放大后UI元素后不显示的问题

如题&#xff1a;UI在game视图显示没有问题&#xff0c; 在Play状态下&#xff0c;在Sence视图查看UI对象的时候进行放大操作&#xff0c;然后UI就不显示了或者显示不全&#xff0c;缩小就恢复正常。这让我在Play模式下预览UI状态很麻烦。相关问题描述较少。 初步判定为摄像机…

力扣:111. 二叉树的最小深度(Python3)

题目&#xff1a; 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCod…

Spring Cloud Gateway实战WebFlux解析请求体及抛出指定错误代码和信息

概述 基于Spring Cloud开发微服务时&#xff0c;使用Spring Cloud原生自带的Gateway作为网关&#xff0c;所有请求都需要经过网关服务转发。 为了防止恶意请求刷取数据&#xff0c;对于业务请求需要进行拦截&#xff0c;故而可在网关服务增加拦截过滤器。基于此&#xff0c;有…

VM虚拟机连接NAT虚拟网络并上网的总结

关键字 VMware、NAT、VM虚拟机、ip route get、网关、私有云 设置 虚拟网络 VMware虚拟网络管理器中显示当前所有VMware的虚拟网络&#xff0c;根据显示&#xff0c;这里是"VMnet8"网络是NAT模式&#xff08;寄主机只能存在一个NAT虚拟网络&#xff0c;也就是说&a…

制作PE启动盘

文章目录 ⭐️写在前面的话⭐️1、下载微PE2、格式化U盘3、安装PE到U盘4、下载镜像 ⭐️写在前面的话⭐️ &#x1f4d2;博客主页&#xff1a; 程序员好冰 &#x1f389;欢迎 【点赞&#x1f44d; 关注&#x1f50e; 收藏⭐️ 留言&#x1f4dd;】 &#x1f4cc;本文由 程序员好…

通俗易懂了解大语言模型LLM发展历程

1.大语言模型研究路程 NLP的发展阶段大致可以分为以下几个阶段&#xff1a; 词向量词嵌入embedding句向量和全文向量理解上下文超大模型与模型统一 1.1词向量 将自然语言的词使用向量表示&#xff0c;一般构造词语字典&#xff0c;然后使用one-hot表示。   例如2个单词&…

【STM32】IAP升级01 bootloader实现以及APP配置(主要)

APP程序以及中断向量表的偏移设置 前言 通过之前的了解 之前的了解&#xff0c;我们知道实现IAP升级需要两个条件&#xff1a; 1.APP程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始&#xff1b; 2.APP程序的中断向量表相应的移动&#xff0c;移动的偏移量为 x&#xff…

深入理解 pytest.main():Python 测试框架的核心功能解析

前言 笔者平常运行pytest用例时&#xff0c;通常使用命令行方式&#xff0c;像这样 pytest -v pxl/test_dir/test_demo.py::TestDemo::test_my_var&#xff0c;执行某一条case&#xff0c;但每次命令行敲也挺麻烦的。那如何在python代码中调用pytest呢&#xff1f;带着疑问一…

APP开发费用计算方法

计算开发移动应用&#xff08;APP&#xff09;的费用涉及多个因素&#xff0c;包括项目的规模、复杂性、所需功能、技术选择、开发团队的经验、地理位置和市场需求等。以下是一些考虑开发APP费用的关键因素以及一般的费用计算方法&#xff0c;希望对大家有所帮助。北京木奇移动…

第八天:gec6818arm开发板和Ubuntu中安装并且编译移植mysql驱动连接QT执行程序

一、Ubuntu18.04中安装并且编译移植mysql驱动程序连接qt执行程序 1 、安装Mysql sudo apt-get install mysql-serverapt-get isntall mysql-clientsudo apt-get install libmysqlclient-d2、查看是否安装成功&#xff0c;即查看MySQL版本 mysql --version 3、MySQL启动…

PHP8中伪变量“$this->”和操作符“::”的使用-PHP8知识详解

对象不仅可以调用自己的变量和方法&#xff0c;也可以调用类中的变量和方法。PHP8通过伪变量“$this->”和操作符“::”来实现这些功能。 1.伪变量“$this->” 在通过对象名->方法调用对象的方法时&#xff0c;如果不知道对象的名称&#xff0c;而又想调用类中的方法…

【新版】系统架构设计师 - 层次式架构设计理论与实践

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 层次式架构设计理论与实践考点摘要层次式体系结构概述表现层框架设计MVC模式MVP模式MVVM模式使用XML设计表现层表现层中UIP设计思想 中间层架构设计业务逻辑层工作流设计业务逻辑层设计 数据访问层…

三维模型3DTile格式轻量化压缩处理重难点分析

三维模型3DTile格式轻量化压缩处理重难点分析 在对三维模型3DTile格式进行轻量化压缩处理的过程中&#xff0c;存在一些重要而又困难的问题需要解决。以下是几个主要的重难点&#xff1a; 1、压缩率和模型质量之间的平衡&#xff1a;压缩技术的目标是尽可能地减少数据大小&…

【机器学习】期望最大算法(EM算法)解析:Expectation Maximization Algorithm

【机器学习】期望最大算法&#xff08;EM算法&#xff09;&#xff1a;Expectation Maximization Algorithm 文章目录 【机器学习】期望最大算法&#xff08;EM算法&#xff09;&#xff1a;Expectation Maximization Algorithm1. 介绍2. EM算法数学描述3. EM算法流程4. 两个问…

【AI视野·今日NLP 自然语言处理论文速览 第四十一期】Tue, 26 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Tue, 26 Sep 2023 Totally 75 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Physics of Language Models: Part 3.1, Knowledge Storage and Extraction Authors Zeyuan Allen Zhu, Yuanz…