声明:
(1) GO版本:go version go1.21.5 windows/amd64
(2) 开发工具:vscode
(3) 微信公众号:给点知识
如果版本不一样再环境变量的配置上多少有点问题。1.11 GO版本之前使用GOPATH 之后可以使用go.mod 要不然导入模块包那块会有问题。
#数据类型-变量 #Go变量
变量相当于内存中一个数据存储空间的表示,一般需要有变量的名称和类型
比如:var name int =18
package main
import "fmt"
func main() {
var 名字 string = "张三"
var 年龄 int = 18
var 身高 float32 = 180.9
fmt.Println(名字, 年龄, 身高)
}
不能以数字开头, 不能使用关键词作为变量,比如int float32 string等,
其实关键词你非要使用也可以使用,但是会有一定的问题。
比如:
定义了:var float32 int = 10
这个时候关键词float32 变成了一个整数,如果你再使用float32定义变量的时候就会报错,因为这个时候它是整数
var score float32 = 19,这个就会报错了。如下图:
区分大小写,可以以字母、下划线开头
package main
import "fmt"
func main() {
var _名字 string = "张三"
var z年龄 int = 18
var Z年龄 int = 20
var 身高 float32 = 180.9
fmt.Println(_名字, Z年龄, z年龄, 身高)
}
package main
import "fmt"
import _ "strconv"
func main() {
var _名字 string = "张三"
var float32 int = 18
fmt.Println(float32, _名字)
}
包名规则
变量使用字母大小写实现,使用小驼峰实现。
创建目录结构
D:.
└─demo01
├─main
|---main.go
└─utils
|---mymath.go
--go.mod // 不用自己创建,接着往下看
1. `go.mod` 文件是一个文本文件,位于项目的根目录下。它记录了项目所依赖的模块及其版本信息,并定义了模块的路径。
2. 创建好文件以及目录后填充内容
3. main.go
package main
import (
f"fmt"
"gdzs/demo01/utils"
)
func main(){
f.Println("---------")
f.Println(utils.PackageName)
}
4. mymath.go
package utils
var Num int = 1
var PackageName string = "这里是工具模块的PackageName变量"
var name string = "名字"
5. cd demo01
6. go mod init gdzs 就会生成go.mod 文件
7. 这个时候执行go demo01/main/main.go即可看到结果
注意,这里因为Code Runner 这个插件执行的目录是在vscode 添加的根目录下执行的,上图就是再01.test目录下执行的。注意如果打开的是上一级目录就会报错,例如
PS D:\07.go\01.test> cd ..
PS D:\07.go> go run .\demo01\main\main.go
CreateFile .\demo01\main\main.go: The system cannot find the path specified.
所以解决办法就是需要保证demo01和go.mod再同一个目录,且上级目录就是vscode打开的根目录,如图所示
#GO变量声明
1. 第一种:直接赋值: var age int = 12
2. 第二种:只复制类型赋值后赋值变量: var num int
3. 第三种:没有写类型,通过值进行自动判断 var name="张三";
4. 第四种:省略var 使用 := 代替
package main
import "fmt"
func main() {
// 第一种变量
var age int = 18
fmt.Println("age is ", age)
// 第二种变量定义方式 不赋值 使用默认值
var num int
fmt.Println("num is ", num)
// 第三种变量如果没有写变量的类型,那么根据=后面的值进行判断类型
var name = "张三"
println("name is:", name)
// 第四种,省略var 使用 【:=】代替
name2 := "里斯"
println("name2 is:", name2)
}
#Go多个变量声明
1. 格式1:var age, name = 18, "张三"
2. 格式2:
var (
n1=18
n2="name"
n3 int = 100
)
package main
import "fmt"
func main() {
var n1, n2, n3 = 19, "java", 7
println(n1, n2, n3)
println("------")
// 定义多个变量,并且赋值多个
var (
m1 int = 10
m2 string = "|王五|"
m3 = 100
)
println(m1, m2, m3)
println("------")
}
#GO全局与局部变量
1. 创建文件main.go
package main
import "fmt"
var globalVariable int = 10
func main() {
fmt.Println(globalVariable) // 输出:10
}
注意全局变量不能使用 先声明后赋值的方式
注意全局变量不能使用 := 定义赋值变量
package main
import "fmt"
/*
实现定义一个学生的信息
并打印出来
*/
var (
name2 = "张三"
age2 int = 12
notes2 = "中国国人"
height2 = 178
)
func main() {
// 第一种定义方式
var name = "jark"
// 第二种第一方法是
var age int = 10
// 第三种就是定义好后在赋值
var notes string
// 第四种 使用:=代替 var
height := 180
notes = "学生的基本信息"
message := fmt.Sprintf("name:%s"+
"\nage:%d"+
"\nheight:%d"+
"\nnotes:%s",
name, age, height, notes)
fmt.Println(message)
fmt.Println("---------------")
fmt.Println("使用全局变量")
message2 := fmt.Sprintf("name2:%s"+
"\nage2:%d"+
"\nheight2:%d"+
"\nnotes2:%s",
name2, age2, height2, notes2)
fmt.Println(message2)
}
为什么这个int8 范围是-128到127呢,这里只讲一个,剩下的都是类似的
1.因为这个int8 有一个字节,一般一个字节表示为8位(一些特定的嵌入式系统或硬件平台可能使用非标准的字节大小,如 6 位、7 位或 9 位。这些非标准字节大小可能出于特定的设计需求或历史原因。)
2.因为是8个比特位,且一般第一位为符号位所以
正数范围就是(二进制表示):00000000-01111111 也就是0-127
负数范围就是(二进制表示):10000000-11111111 可以看到 是负数的0 到-127
那么问题来了,哪来的-128呢?
因为0 这个数没有正负之分,所以就把10000000 这个位用于表示-128 所以这里的范围就是-128-127了
package main
import "fmt"
func main(){
var age1 int8 = 23
var age2 int16 = 28
var age3 int32 = 18
var age4 int64 = 21
fmt.Printf("age1=%d,type=%T", age1, age1)
fmt.Println()
fmt.Printf("age2=%d,type=%T", age2, age2)
fmt.Println()
fmt.Printf("age3=%d,type=%T", age3, age3)
fmt.Println()
fmt.Printf("age4=%d,type=%T", age4, age4)
}
// 输出结果
age1=23,type=int8
age2=28,type=int16
age3=18,type=int32
age4=21,type=int64
有意思的是:如果你输出的整数超出范围,那么编译器会自动标红,编译的时候无法通过,这也是go语法的严谨性。
package main
/*
求两个数的和,和的结果分别为
500; 1,000; 200,000; 9,000,000,000
*/
import "fmt"
func main() {
var num1 uint8 = 249
var num2 uint8 = 251
fmt.Printf("%d+%d=", num1, num2)
// 以下赋值导致数据溢出
// var sum1 = num1 + num2
sum1 := uint16(num1) + uint16(num2)
fmt.Printf("%d; sum1类型是:%T\n", sum1, sum1)
// 同理1000 也是这么计算的
var num3 uint16 = 500
var num4 uint16 = 500
fmt.Printf("%d+%d=", num3, num4)
// 以下赋值导致数据溢出
// var sum1 = num1 + num2
sum2 := num3 + num4
fmt.Printf("%d; sum2类型是:%T\n", sum2, sum2)
// 剩下的两个自己动手实现了
}
rune 有符号 等价于int32 这个类型是GO独特的,其实它就是int32的别名,翻译中文为符文的意思,
Go语言引入了rune
类型,主要是为了处理Unicode字符。Unicode是一种字符集,包含了几乎所有世界上使用的字符,包括不同语言的字母、符号、表情符号等。用了别名rune带有符文符号的意思,所以这里用了rune 其实大家记住是int32就行了。
至于为什么不用uint32 主要怕后面unicode出现负数情况。但是现在没出现,为的是将来,将来懂么!
至于unicode字符集是什么:Unicode字符集旨在覆盖全世界范围内的语言和符号
byte 无 等价于uint8
package main
/*
其它类型
int uint rune byte
*/
import "fmt"
func main() {
var num1 int = 100000000
var num2 rune = 72
var num3 uint = 111111111111
var num4 byte = 121
fmt.Printf("num1=%d,num2=%d,num3=%d"+
"num4=%d,rune2=%c",
num1, num2,
num3, num4, num4,
)
}
// 输出结果
num1=100000000,num2=72,num3=111111111111num4=121,rune2=y
其中%c表示输出字符
42
,它将被认为是int类型。int8
:最大值为127int16
:最大值为32767int32
:最大值为2147483647int64
:最大值为9223372036854775807uint8
(即byte
):最大值为255uint16
:最大值为65535uint32
:最大值为4294967295uint64
:最大值为18446744073709551615math/big
包中的big.Int
类型,它可以表示任意大小的整数。举例使用big创建更大的数
import “big"
var num7 = new(big.Int)
num7.SetString("15646545646545456456454546545465445623", 10)
fmt.Print(num7)
//使用自大的答应方法
println(num7.String())
#浮点类型 #Go变量浮点类型
package main
/*
浮点类型
*/
import "fmt"
func main() {
var f1 float32 = 123.0000000016
var f2 float64 = 123.0000000016
println(f1, f2, " 结果1")
fmt.Println(f1, f2, " 结果2")
fmt.Print(f1, f2, " 结果3")
}
// 打印结果
+1.230000e+002 +1.230000e+002 结果1
123 123.0000000016 结果2
123 123.0000000016 结果3
科学计数法
注意:如果没有指定浮点类型,那么默认就是float64
package main
/*
浮点数科学计数法
*/
import "fmt"
func main() {
// 定义浮点类型
var k1 float32 = 3.14
// 定义科学计数法10的-2次方 大写E
var k2 float32 = 314e-2
// 定义科学计数法10的-2次方 小写e
var k3 float32 = 3141592654e-2
// 定义科学计数法10的2次方 大写E
var k4 float64 = 0.03141592654e+2
// 定义科学计数法10的-2次方 小写e
var k5 float32 = 0.0314e+2
message := fmt.Sprintf("k1:%g\n"+
"k2:%g\n"+"k3:%g\n"+
"k4:%g\n"+"k5:%g\n",
k1, k2, k3, k4, k5,
)
fmt.Println(message)
k6 := 3.1
// 查看默认的类型
fmt.Printf("%T", k6)
}
//打印结果
k1:3.14
k2:3.14
k3:3.1415926e+07
k4:3.141592654
k5:3.14
float64
// 小知识:
%e 科学计数法,如-1234.456e+78
%E 科学计数法,如-1234.456E+78
%f 有小数部分但无指数部分,如123.456
%F 等价于%f
%g 根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
%G 根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)
package main
import "fmt"
func main() {
var c1 int = '中'
fmt.Println(c1)
fmt.Printf("%c", c1)
// 字符类型本质上就是一个整数
var c2 int = 97
fmt.Printf("%c\n", c2)
// ascii 使用的是byte,但是如果是unicode那就需要使用int类型了
// 想显示字符那就需要使用字符集进行
}
// 打印结果
20013
中a
简介:转义字符\ 将后面的字母表示为特殊含义
实战测试
package main
import "fmt"
func main() {
// \b 退格键盘
fmt.Println("-你好\b中国=")
// \n 换行
fmt.Println("-你好\n中国=")
// \r 光标回到开头
fmt.Println("-你好\r中国=")
// \t tab的作用
fmt.Println("-你好\t中国=")
}
/*
输出结果:
-你好中国=
-你好
中国=
中国=
-你好 中国=
*/
package main
import "fmt"
func main() {
// 布尔类型定义
var status bool = true
var is_false bool = false
fmt.Println(status)
fmt.Println(is_false)
// 逻辑运算
is_true := 5 > 8
fmt.Println(is_true)
}
/*
true
false
false
*/
package main
import "fmt"
func main() {
var s1 string = "小日子过得不错的"
fmt.Println(s1)
var s2 string = "王侯将相,宁有种乎"
fmt.Println(s2)
// 中文变量
var 爱好 = "爱好水果和爬山"
fmt.Println(爱好)
// 带有特殊字符的话,需要使用反引号
var s3 = `中国阁雪云低,卷沙风急,
惊雁失序。户掩寒宵,屏闲冷梦,
灯飐唇似语。堪怜窗景,都闲刺绣,
但续旧愁一缕。邻歌散,罗襟印粉,
袖湿茜桃红露。
西湖旧日,留连清夜,爱酒几将花误。
遗袜尘销,题裙墨黯,天远吹笙路。吴
台直下,缃梅无限,未放野桥香度。
重谋醉,揉香弄影,水清浅处。`
fmt.Println(s3)
var s4 = "你好" + "给点知识" +
"公众号你关注了了?" +
"赶紧扫码关注下呢?"
s4 += "感谢您的关注!!"
fmt.Println(s4)
}
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
var a1 int
var a2 string
var a3 uint
var a4 byte
var a5 bool
fmt.Println(a1)
fmt.Println(a2)
fmt.Println(a2=="")
fmt.Println(a3)
fmt.Println(a4)
fmt.Println(a5)
}
// 输出结果
Hello world!
0
true
0
0
false
float a = 3.14;
int b = (int)a; // 显式将浮点数转换为整数
(2)隐式转换:隐式转换是指在某些情况下,编程语言会自动将一个数据类型转换为另一个数据类型,而无需显式地指定转换操作。这种转换是编译器自动进行的,通常涉及数据类型之间的兼容性或类型提升的情况。例如,将一个整数赋值给一个浮点数变量,或将一个字符赋值给一个整数变量等。
int a = 5;
float b = a; // 隐式将整数转换为浮点数
在Go使用隐式转换,会出现报错,编译都无法通过如下图:
注意:GO语言中只有显式转换。
也就是:
package main
// 类型转换
import "fmt"
func main() {
// 类型转换
var a1 int = 100
fmt.Println(a1)
// 隐式转换 var a2 float32 = a1 这种方式转换是不行的
var a2 float32 = float32(a1)
// 注意:这里只是把a1 得值类型转为了float32
// 而a1类型还是原来的int
fmt.Printf("a1=%d,type=%T, a2=%f,type=%T",
a1, a1, a2, a2)
fmt.Println()
// 将float64 转为int8 得时候 编译不会出错,但是会数据得溢出
var a3 int64 = 99999
// 因为类型不同所以溢出了
var a4 int8 = int8(a3)
fmt.Println(a3, a4)
var a5 int32 = 88
// 会直接溢出
var a6 int8 = int8(a5) + 127
// 编译不会通过
var a7 int8 = int8(a5) + 128
fmt.Println(a6)
fmt.Println(a7)
}
/*
//1.编译不通过:var a7 int8 = int8(a5) + 128
# command-line-arguments
12.go\goproject\src\demo11\main.go:26:27: 128 (untyped int constant) overflows int8
//2.编译不通过给:注释掉以编译不通过的代码。输出结果:
100
a1=100,type=int, a2=100.000000,type=float32
99999 -97
-41
*/
format string
:这是一个格式字符串,用于指定输出的格式。格式字符串中可以包含普通文本和格式化动词(例如%d
、%s
、%f
等),用于插入可变参数的值。格式化动词告诉Sprintf
函数如何将参数转换为字符串并插入到格式字符串中。a ...interface{}
:这是可变参数列表,允许传递任意数量的参数。这些参数的类型可以是任何类型,因为它们的值将在运行时根据格式字符串的指示进行转换并插入到最终的字符串中。package main
// 2.8 数据类型转换
// 基本类型转为string类型
import "fmt"
func main() {
// 整型转为字符串类型
var age int = 19
var s1 string = fmt.Sprintf("age=%d,type=%T", age, age)
fmt.Println(s1)
// 浮点型转为字符串类型
var score float32 = 98.89
s2 := fmt.Sprintf("score=%f, type=%T", score, score)
fmt.Println(s2)
// 布尔类型转为字符串类型
var status bool = true
s3 := fmt.Sprintf("status=%t, type=%T", status, status)
s4 := fmt.Sprintf("%t", status)
fmt.Println(s3)
fmt.Println(s4 == "true")
// 字符类型转为字符串类型
var gender byte = 'm'
s5 := fmt.Sprintf("gender=%c", gender)
s6 := fmt.Sprintf("%c", gender)
fmt.Println(s5)
fmt.Println(s6 == "m")
// 报错:main.go:32:20: invalid operation:
// s6 == 'm' (mismatched types string and untyped rune)
// 在Go语言中,'m'是一个字符字面量,表示一个单个的字符。
// 而变量s6是一个字符串,因此在比较s6和'm'时会产生类型不匹配的错误。
// fmt.Println(s6 == 'm')
}
// 输出结果:
age=19,type=int
score=98.889999, type=float32
status=true, type=bool
true
gender=m
true
(2)使用strconv:这块可以参考具体的文档,一般不使用这种方法转换
package main
import (
"fmt"
"strconv"
)
func main() {
// 整型转字符串
var age int = 18
var s1 string = strconv.FormatInt(int64(age), 10)
fmt.Printf("my age is %s", s1)
fmt.Println()
// 浮点类型转字符串
var score float32 = 2.8
// FormatFloat(要转换的值,)
// func FormatFloat(f float64, fmt byte, prec, bitSize int) string
var s2 string = strconv.FormatFloat(float64(score), 'f', 1, 32)
fmt.Println(s2)
// 布尔类型转字符串
var status bool
var s3 string = strconv.FormatBool(status)
fmt.Println(s3)
}
package main
// 字符串转为基本类型
import (
"fmt"
"strconv"
)
func main() {
var s1 string = "true"
var b1 bool
var err1 error
// 这里返回两个值,所以使用两个参数
b1, err1 = strconv.ParseBool(s1)
fmt.Printf("b1=%t,type=%T, error=%s", b1, b1, err1)
fmt.Println()
// 我们也可以使用占位符 _ 来接收参数
b1, _ = strconv.ParseBool(s1)
fmt.Printf("b1=%t,type=%T", b1, b1)
fmt.Println()
// 整型转换 0x16 十进制=22
var s2 string = "16"
var i1 int64
// 三个参数
// 第一个是字符串 第二个是字符串的进制8进制
i1, _ = strconv.ParseInt(s2, 8, 64)
fmt.Printf("i1=%d", i1)
fmt.Println()
var s3 string = "128"
var i2 int64
// 三个参数
i2, _ = strconv.ParseInt(s3, 0, 8)
fmt.Printf("i1=%d", i2)
// 直接转
fmt.Println()
var er error
i2, er = strconv.ParseInt("112s23", 0, 8)
fmt.Printf("i1=%d, er=%s", i2, er)
// 直接转 16进制的16 10进制是22
fmt.Println()
i2, _ = strconv.ParseInt("0x16", 0, 8)
fmt.Printf("i1=%d", i2)
}
// 输出结果
// b1=true,type=bool, error=%!s(<nil>)
// b1=true,type=bool
// i1=14 // 字符串16是8进制,所以10进制表示就是14
// i1=127 // 128是十进制 但是第三个参数是8bit 溢出了,所以是127
// i1=0, er=strconv.ParseInt: parsing "112s23": invalid syntax
// i1=22
总结:
简介:指针就是指向地址的变量
(1)我们定义的变量编译器再执行的时候都会给变量在内存中给它申请一个空间,这个空间有对应的地址,我们用来存储这个地址的变量就叫做指针
(2)定义指针使用*类型 比如*int 即可
var ptr1 *int
var ptr2 *float32
var ptr2 *float64
实战测试
(1)取出对应的指针地址使用&
var age int = 19
var *ptr *int = &age
(2)* 根据地址取出对应的值使用星
var *ptr *int = &age
fmt.Println(*ptr)
完成代码如下:
package main
// 指针类型
import "fmt"
func main() {
var age int = 22
var ptr *int = &age
var ptr1 **int = &ptr
fmt.Println("age 的地址是", &age)
fmt.Printf("age=%d,ptr=%v", age, ptr)
fmt.Println()
fmt.Println("使用指针打印出值:", *ptr)
fmt.Println("ptr指针的地址:", &ptr)
fmt.Println("ptr1指针的地址:", &ptr1)
}
输出结果:
// age 的地址是 0xc00000a0c8
// age=22,ptr=0xc00000a0c8
// 使用指针打印出值: 22
// ptr指针的地址: 0xc00006c020
// ptr1指针的地址: 0xc00006c028
var name string = "张三"
ptr *string = &name
*ptr = "里斯"
完整代码演示如下:
package main
// 通过在指针修改值
import "fmt"
func main() {
// 通过在指针修改值
var name string = "张三"
var ptr2 *string = &name
fmt.Printf("name的初始值是:%v", name)
fmt.Println()
fmt.Printf("ptr2指针地址是:%v, 值是:%v", ptr2, *ptr2)
fmt.Println()
fmt.Println("------分割线------")
// 修改值
*ptr2 = "里斯"
fmt.Printf("ptr2修改值后name的值是:%v", name)
fmt.Println()
fmt.Printf("ptr2修改值后的地址:%v, 值是:%v", ptr2, *ptr2)
}
输出结果:
//name的初始值是:张三
//ptr2指针地址是:0xc00008a030, 值是:张三
//------分割线------
//ptr2修改值后name的值是:里斯
//ptr2修改值后的地址:0xc00008a030, 值是:里斯
(2)指针变量接收的一定是地址值
一旦赋值的是其他类型就会报错,这里很好理解,就是ptr2本来是指针类型,你非要赋值其他类型肯定会报错的。所以这里我们要赋值对应的类型的值。
(3)指针变量的地址必须匹配对应的类型。基本数据类型,都有对应的指针类型,形式为数据类型,比如int的对应的指针就是int float32对应的指针就是*int float32对应的就是*float32。要不然会报错,如下:
var ptr *int
var socre float32 = 98.9
ptr = &score
报错内容:main.go:31:18:在变量声明中,不能使用 &socre(*float32 类型的值)作为 *int 值
#GO语言关键字
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
#GO语言标识符
append bool byte cap close
complex complex64 complex128 copy true
uint uint8 uint16 uint32 uint64
int int8 int16 int32 int64
float32 float64 make new
imag iota len nil
print println panic uintprt
real recover string flase
package main
import "fmt"
func main() {
var name string
var age int
var gender bool
fmt.Println(name)
fmt.Println(age)
fmt.Println(gender)
}
描述
给定两个变量a,b,判断两个变量的地址,值(a,b的地址取得)是否相等,将结果依次存入切片,并返回。
知识点:
Go语言中的指针操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)。
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行“取地址”操作。 Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等。
示例1
输入:
1,2
复制
返回值:
[false,false]
-----------参考答案
package main
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param a int整型 变量a
* @param b int整型 变量b
* @return bool布尔型一维数组
*/
func equal( a int , b int ) []bool {
// write code here
result := []bool{&a==&b, a==b}
return result
}
fmt.Sprintf
的返回值是一个格式化后的字符串。fmt.Sprint
的返回值是将输入参数转换为字符串后连接在一起的结果。package main
// 2.8 数据类型转换
// 基本类型转为string类型
import "fmt"
func main() {
// 整型转为字符串类型
var age int = 19
// 字符类型转为字符串类型
var gender byte = 'm'
s6 := fmt.Sprintf("%c", gender)
s7 := fmt.Sprint("My age is ", s6, " and I am ", age, " years old.")
fmt.Println(s7)
}
// 输出结果
My age is m and I am 19 years old.
下一个文章:
大致内容:一二章节总结和GO语言基础题目