目录
github: GitHub - jerrycgao/GoStudy
go 下载 :https://go.dev/dl/
MAC安装go
gaocong@JERRYCGAO-MB0 ~ % go version
go version go1.20.1 darwin/amd64
开发工具GoLand
1 入门程序
// 文件所在包,go的每个文件都必须属于一个包
package main
//导入包,导入包使用包中的函数
import "fmt"
// func main: 定义函数
func main() {
fmt.Print("Hello World")
}
运行输出:
Hello World
1.1 重要网址
Go的官网指导:Documentation - The Go Programming Language
Go的API库文档:Go Packages
Go在线调试器:The Go Programming Language
中文文档 : Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国
1.2 定义变量
func main() {
//有符号
var i int = 1
fmt.Println("i=", i)
//无符号
var num1 uint8 = 255
fmt.Print("num1=", num1)
//查看数据类型
fmt.Printf("num1的类型是 %T \n", i)
//查看变量的字节大小
var n2 int64 = 10000000
fmt.Printf("n2的类型是%T,占用的字节数数是 %d", n2, unsafe.Sizeof(n2))
//原则尽量使用最小
//byte 可以表示0-255
var c byte = 255
fmt.Print("c=", c)
}
不能改变数据类型,编译无法通过:
num2 := 100
fmt.Println("num2=", num2)
//num2 = 1.1 不能该改变数据类型
使用方式
1、声明,不赋值,使用默认值
2、声明的同时赋值,类型推导
3、省略var ,注意左边的变量不应该是已经声明过的,否则会导致错误,
name := "acong"
4、多变量赋值,a,b,c := "a", "b", "c"
5、+ 使用,都是数字做加法运算, 有字符串做拼接。
2 数据类型
基本类型:
1、数字类型: 整型 , 浮点类型
2、字符型: byte
3、布尔类型
4、字符串
复杂类型:
1、指针
2、数组
3、结构体
4、管道
5、函数
6、切片 slice
7、接口 interface
8、map
2.1 数字类型
有符号类型int:
如果不声明类型的话,默认的类型都是占用64位(如果机器是32位的话,默认是32位)
rune 与 int32 等价
超出范围无法编译:
var i int8 = 129
//cannot use 129 (untyped int constant) as int8 value in variable declaration (overflows)
无符号的数字类型uint :
如果不声明类型的话,默认的类型都是占用64位(如果机器是32位的话,默认是32位)
浮点类型float:
//浮点类型
var price float32 = 89.12
fmt.Println("price=", price)
//默认类型
var num3 = 1.4
fmt.Printf("num3 %T \n", num3)
//科学计数法
var num4 = 5.342E4
fmt.Println("num4=", num4)
没有默认的float ,不受OS影响
不声明类型默认是64位
2.2 字符类型
go没有专门的字符类型(java中的char),go存储单个字母用,一般用byte来保存
字符串就是一串有固定长度的字符链接起来的字符序列,Go的字符串是单个字节连接起来的,对于传统的字符串是由字符组成的,Go的字符串是自己字节组成的,有所不同。
//字符类型
var c1 byte = 'a'
var c2 byte = '0'
fmt.Println("c1=", c1)
fmt.Println("c2=", c2)
//直接输出字符,就是输出了字符的码值
//输出字符,格式化输出
fmt.Printf("c1=%c, c2=%c \n", c1, c2)
//中文
//var c3 byte = '我' //不能存贮中文 untyped rune constant 25105 溢出
var c3 int = '我'
fmt.Printf("c3=%c", c3)
//ASKII 表中的值可以直接用byte存贮,超过这个值可以用uint或者int存储,然后格式化输出
注意事项:
1、字符常量用单引号, 中文要用int存储,字符本质是一个数字,输出要用格式化输出%c,输出该数字对应的unicode的字符,
2、Go中可以用转义字符
3、Go语言中文用UTF-8编码,英文字母一个字节,中文-3个字节
4、字符可以参与运算
字符本质:
1、字符型,存储到计算机,存储的是对应的码值
存储: 字符 -- > 对应的码值 --> 二进制 --> 存储
读取:二进制 --> 码值 ---> 字符 ---> 读取
2、Go的编码统一集成了utf-8,不会有编码乱码的问题。
2.3 布尔类型
bool : true or false 占用1个字节
bool类型只能给true 或者false,不能用数字0或者非0替代 ,编译直接会报错
//布尔类型
var b1 = true
var b2 = false
fmt.Println("b2=", b2)
fmt.Printf("b1占用大小=%d", unsafe.Sizeof(b1))
2.4 String类型
func main() {
var str1 = "Hello"
fmt.Println("str1 =", str1)
//注意事项
//1、utf-8统一编码
//2、string对象是不可变对象
//var str2 = "world"
//str2[0] = 'x' //不能修改str2的内容
//3、双引号:会识别转义字符 , 反引号:不会识别转义字符
var str3 = "abc \n def"
fmt.Println("str3 =", str3)
var str4 = `abc \n def`
fmt.Println("str4 =", str4)
//4、拼接
var str5 = "Jerry" + str1
fmt.Println("str5 =", str5)
//5、多个字符串拼接,+ 要留在上面
var str6 = "Hello" + "Hello" + "Hello" + "Hello" +
"OK "
fmt.Println("str6 =", str6)
}
2.5 基本类型的默认值
如果声明没有赋值,就会保留默认值。
2.6 基本数据类型的相互转换
Go中不同类型的变量之不能自动转换,需要显式转换。
2.6.1 基本语法
T(V) T要转换的类型, V被转换的变量
func main() {
var num1 int = 100
fmt.Printf("num1的类型%T \n", num1)
var num2 float32 = float32(num1)
var num3 int8 = int8(num1)
fmt.Printf("num2的类型%T \n", num2)
fmt.Printf("num1的类型%T \n", num1)
fmt.Printf("num3的类型%T", num3)
//大数据类型,转小类型, 溢出处理
var num4 int64 = 99999
var num5 int8 = int8(num4)
fmt.Printf("num5的类型%T,num5=%v \n", num5, num5)
//表达式类型赋值
var num6 int32 = 10
var num7 int64
var num8 int8
//num7 = num6 + 10 //编译不通过
//num8 = num6 + 20 //编译不通过
num7 = int64(num6) + 10
num8 = int8(num6) + 20
fmt.Println("num7=", num7)
fmt.Println("num8=", num8)
//注意运算会有溢出的问题
}
任务类型的转换都需要强制转换。
1、转换只是将对象的值转换给其他变量赋值,原来的对象类型不发生变化
2、注意数字类型赋值会有溢出的问题
2.6.2 String类型与基本数据类型
基本类型转String
func main() {
var num1 int = 100
fmt.Printf("num1的类型%T \n", num1)
var num2 float32 = float32(num1)
var num3 int8 = int8(num1)
fmt.Printf("num2的类型%T \n", num2)
fmt.Printf("num1的类型%T \n", num1)
fmt.Printf("num3的类型%T", num3)
//大数据类型,转小类型, 溢出处理
var num4 int64 = 99999
var num5 int8 = int8(num4)
fmt.Printf("num5的类型%T,num5=%v \n", num5, num5)
//表达式类型赋值
var num6 int32 = 10
var num7 int64
var num8 int8
//num7 = num6 + 10 //编译不通过
//num8 = num6 + 20 //编译不通过
num7 = int64(num6) + 10
num8 = int8(num6) + 20
fmt.Println("num7=", num7)
fmt.Println("num8=", num8)
//注意运算会有溢出的问题
//转String类型 方法1:
var value1 int = 100
var value2 float64 = 100.40
var b bool = false
var mychar byte = 'a'
var str string
str = fmt.Sprintf("%d", value1)
fmt.Printf("str type is %T, str=%v \n", str, str)
str = fmt.Sprintf("%f", value2)
fmt.Printf("str type is %T, str=%v \n", str, str)
str = fmt.Sprintf("%t", b)
fmt.Printf("str type is %T, str=%q \n", str, str)
str = fmt.Sprintf("%c", mychar)
fmt.Printf("str type is %T, str=%q \n", str, str)
//方式2
str = strconv.FormatInt(int64(value1), 10)
fmt.Printf("str type is %T, str=%q \n", str, str)
var num9 float64 = 10.908
str = strconv.FormatFloat(num9, 'f', 2, 64)
fmt.Printf("str type is %T, str=%q \n", str, str)
str = strconv.FormatBool(b)
fmt.Printf("str type is %T, str=%q \n", str, str)
//int转string
var num10 int = 10
str = strconv.Itoa(num10)
fmt.Printf("str type is %T, str=%q \n", str, str)
}
2.6.3 String转基本类型
func main() {
var str1 string = "true"
b, _ := strconv.ParseBool(str1)
fmt.Printf("b type is %T, b=%v \n", b, b)
var str2 string = "100"
value, _ := strconv.ParseInt(str2, 10, 64)
fmt.Printf("value type is %T, value=%v \n", value, value)
var str3 string = "100.901"
float, _ := strconv.ParseFloat(str3, 64)
fmt.Printf("float type is %T, float=%v \n", float, float)
var str4 string = "10"
parseUint, _ := strconv.ParseUint(str4, 10, 8)
fmt.Printf("parseUint type is %T, parseUint=%v \n", parseUint, parseUint)
//转换失败,返回值改类型的默认值,程序不会报错
var str5 string = "hello"
value5, _ := strconv.ParseInt(str5, 10, 64)
fmt.Printf("value5 type is %T, value5=%v \n", value5, value5)
}
2.7 指针
基本类型: 变量存的是值,值类型, 通过&var 可以获取变量在内存中的值
指针类型,指针变量存的值是变量的地址
func main() {
var num1 int = 10
fmt.Println("num1的地址是=", &num1)
//num1的地址是= 0xc0000ac008
var prt *int = &num1
//1、prt 是一个指针变量
//2、ptr的类型是 *int
//3、prt本身的值是&num1
fmt.Printf("ptr = %v \n", prt)
fmt.Println("prt的地址是=", &prt)
//取出ptr指向的值
fmt.Printf("ptr = %v \n", *prt)
//注意事项:
*prt = 20
fmt.Printf("num=%v", num1)
//var num2 int = 300
//var ptr2 *float64 = &num2
//指针类型不匹配。
}
2.8 值类型和引用类型的说明
值类型: int 、 float、bool、string、数组 、 结构体struct
引用类型: 指针、slice切片、map、管道chan、interface 等都是引用类型
说明:
1、值类型,变量直接存储值,内存通常在栈内存中分配
2、变量存储的是一个地址,这个地址对应的空间才是真正存储数据值,内存通常在堆中分配,当没有任何变量引用这个地址时, 该地址对应的数据空间就成为一个垃圾,由GC来回收。
2.9 标识符命名规范
标识符:变量名,方法,函数名
规范:
- 英文字母,下划线 组成
- 数字不可开头
- 不能包含空格
- 下划线_ 称为空标识符,可以代表任何其他标识符,对应的值被忽略,作为占位符使用,不能被使用
- 不能使用系统保留关键字
注意事项:
- 包名和文件夹名一致,不一定必须,尽量保持一致,小写字母
- 变量名、函数名、常量名:采用驼峰命名,
- 变量名、函数名、常量名首字母大写可以被其他包访问,如果首字母小写,只能被本包中使用, Go中没有public和private关键字