文章目录
- 1. 前言:
- 2. go的下载与配置
- 3. Golang 目录结构
- 4. Golang 的基础语法
- 4.1. 变量声明
- 4.2. 输入输出
- 4.3. 条件控制
- 4.4. 数组和切片
- 4.5. 映射表
1. 前言:
根据鼠鼠的实习投递经历,由于越来越多中大型公司都使用 Golang,在现在这个越来越内卷的后端就业环境下,学习一下 Golang 拓宽技术栈面是必须的,下面就跟着鼠鼠进行一些基础知识点的比较和学习吧。
2. go的下载与配置
配置思路与 JAVA 别无二致,这里我只写选择 x64 windows的最新版本(1.22.3 稳定版)
,我选择的是 zip 版的,需要自己配置环境变量的。
- 解压到一个目录里
- 我喜欢把变量添加到用户变量里,把 安装的go目录的bin路径添加到系统变量即可。
- 安装成功
3. Golang 目录结构
Golang 主要有两种目录结构,Go mod模式(),Go PATH()模式
- Go Modules 是 Go 1.11 版本引入的一种新的包管理方式,旨在解决依赖管理和版本控制的问题。
- GOPATH 模式是旧版本 Go 中使用的一种包管理方式,它要求你将所有的 Go 项目都放在一个统一的工作空间(即 GOPATH)下
简单理解就是简单项目吧源代码放一起,通过路径引用依赖,复杂代码项目,通过mod文件管理依赖,类似与 Java 的 Maven。
main 方法作为 go 源代码执行的入口。通常在 package main 包下
go 语言编译不同于JAVA 编译成 JVM 字节码,而是将源代码编译成平台可识别的二进制码,因此体积更小,不需要其他环境支持
- go run = 编译 + 执行(需要 Go 环境支持)
- go build = 编译 (需要go 环境支持)
- 二进制码不需要go 环境支持,直接就可以运行,不过会丧失跨平台特性
4. Golang 的基础语法
go 的语法思路是基于c 语言的,但是加了很多语法糖,有着很多 JAVA 成熟语言的特性,也简化了 JAVA 的繁琐,思路和一众语言差不多。
😄 虽然 Golang 不排斥面向 var name:int = 1
对象,但是由于 Go 不像 JAVA 一样 结构体和方法一样有强关联,不建议面向对象编程
4.1. 变量声明
go的基本数据类型主要有
基本类型
- 布尔型 (
bool
):
- 只能是
true
或false
。
var isActive bool = true
- 整型:
- 不同大小和符号的整型(如
int8
,int16
,int32
,int64
,uint8
,uint16
,uint32
,uint64
)。 int
和uint
类型的大小依赖于执行程序的操作系统(32位或64位)。
var age int = 30 var uAge uint = 30
- 浮点型:
float32
,float64
。
var temperature float64 = 36.6
- 复数类型:
complex64
,complex128
。
var complexNumber complex128 = complex(5, 7)
- 字符串 (
string
):
- UTF-8 字符序列。
var name string = "John Doe"
- 字节 (
byte
) 和符文 (rune
):
byte
是uint8
的别名,用于处理原始数据。rune
是int32
的别名,表示一个 Unicode 码点。
var b byte = 'a' var r rune = '你'
- go 的类型推断语法糖
func main() {
// 使用 := 声明并初始化变量,编译器会根据初始化表达式的类型推断变量类型
name := "Alice"
age := 30
height := 175.5
// 输出变量值
fmt.Println("Name:", name)
fmt.Println("Age:", age)
fmt.Println("Height:", height)
}
- go 的变量交换语法糖
package main
import "fmt"
func main() {
a := 'a'
b := 'b'
a, b = b, a
fmt.Println(a, b)
}
😄 妈妈再也不用担心不会写冒泡排序了!
4.2. 输入输出
go 的输入输出在逻辑和感觉上比 JAVA 更为统一
Java 的 常用的Scanner 和 System.out.println()给人一种很割裂的感觉。
go 通过 fmt 包的函数进行操作
package main
import "fmt"
func main() {
var name string
var age int
fmt.Println("Enter your name and age:")
fmt.Scanln(&name, &age)
fmt.Printf("Hello, %s! You are %d years old.\n", name, age)
}
4.3. 条件控制
go的条件控制和 Java 类似 , 更自由一些,常用的 if 举例:
if condition1 {
// 如果条件1为真,则执行这里的代码块
} else if condition2 {
// 如果条件1为假且条件2为真,则执行这里的代码块
} else {
// 如果以上条件都不满足,则执行这里的代码块
}
if x := 5; x > 0 {
fmt.Println("x is positive")
} else {
fmt.Println("x is non-positive")
}
if 里可以进行变量声明
switch 也是常用的条件控制语句。
switch expr {
case case1:
statement1
case case2:
statement2
default:
default statement
}
4.4. 循环
go 的循环是我最喜欢的设计,尤其是在迭代的时候可以获取下标,要知道 Java 中使用迭代器迭代是无法获取下标的。
func main() {
for i := 1; i <= 9; i++ {
for j := 1; j <= 9; j++ {
if i <= j {
fmt.Printf("%d*%d = %2d ", i, j, i*j)
}
}
fmt.Println()
}
}
这个可以配合可迭代对象使用,类似 Java 增强 for 循环,迭代器加强版,可以获取下标
func main() {
sequence := "hello world"
for index, value := range sequence {
fmt.Println(index, value)
}
}
4.4. 数组和切片
切片类似动态数组,由于 Java 中没用动态数组,一般使用 ArrayList 替代,但是数组和 List 使用方式不同,兼容性差,而切片使用方法和数组几乎相同,但是又可以自动扩容。
package main
import "fmt"
func main() {
//数组声明
var numbers [5]int
numbers = [5]int{1, 2, 3}
numbers1 := new([5]int)
numbers1[0] = 0
//切片声明
var slice []int
slice1 := make([]int, 5, 5)
fmt.Println(numbers[0], slice[0], slice1[0])
}
make函数接收三个参数:类型,长度,容量。举个例子解释一下长度与容量的区别,假设有一桶水,水并不是满的,桶的高度就是桶的容量,代表着总共能装多少高度的水,而桶中水的高度就是代表着长度,水的高度一定小于等于桶的高度,否则水就溢出来了。所以,切片的长度代表着切片中元素的个数,切片的容量代表着切片总共能装多少个元素,切片与数组最大的区别在于切片的容量会自动扩张
4.5. 映射表
go中的映射表和 Java 中的 hashMap 有点类似
mp := map[int]string{
0: "a",
1: "a",
2: "a",
3: "a",
4: "a",
}
mp := map[string]int{
"a": 0,
"b": 22,
"c": 33,
}
//通过make 创建
mp := make(map[string]int, 8)
mp := make(map[string][]int, 10)