社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
https://golang.google.cn/dl/
下载windows sdk,并安装
配置环境变量,go1.17.6.windows-amd64.msi安装后会默认配置GOROOT,只需要重新配置GOPATH,用于指向工作目录(项目存放目录)
验证是否安装成功
go version
两种执行流:
两种执行流的区别
通过go build可以生成指定文件名的可执行文件
go build -o myhello.exe hello.go
package main
import "fmt"
// 定义全局变量
var b = 3
var c = "cc"
var (
d = 4
e = "ee"
)
func main() {
// 第一种:完整定义并赋值
var a int = 1
fmt.Println("a=", a)
// 第二种:指定变量类型,若不赋值,则使用默认值
var i int
fmt.Println("i=", i)
// 第三种:根据值自行判断变量类型(类型推导)
var num = 10.11
fmt.Println("num=", num)
// 第四种:省略var,注意 := 左侧的变量不能是之前申明过的,否则会报错
// 下面方式等价于 var name string = "tom"
name := "tom"
fmt.Println("name=", name)
// 一次申明多个变量
var n1, n2, n3 int
fmt.Println("n1=", n1, "n2=", n2, "n3=", n3)
var n4, n5, n6 = 4, "tom", 6
fmt.Println("n4=", n4, "n5=", n5, "n6=", n6)
n7, n8, n9 := 7, "tom8", 9
fmt.Println("n7=", n7, "n8=", n8, "n9=", n9)
fmt.Println("b=", b, "c=", c, "d=", d, "e=", e)
// 加号的使用
// 两边是数值类型,则是做加法运算
var m1 = 1
var m2 = 2
var m3 = m1 + m2
fmt.Println("m3=", m3)
// 两边有字符串,则是做拼接
var m4 = "m4"
var m5 = "m5"
var m6 = m4 + m5
fmt.Println("m6=", m6)
}
类型 | 有无符号 | 占用存储空间 | 数据范围 | 备注 |
---|---|---|---|---|
int8 | 有 | 1字节 | -128 ~ 127 | |
int16 | 有 | 2字节 | -2^15 ~ 2^15-1 | |
int32 | 有 | 4字节 | -2^31 ~ 2^31-1 | |
int64 | 有 | 8字节 | -2^63 ~ 2^63-1 | |
uint8 | 无 | 1字节 | 0 ~ 255 | |
uint16 | 无 | 2字节 | 0 ~ 2^16-1 | |
uint32 | 无 | 4字节 | 0 ~ 2^32-1 | |
uint64 | 无 | 8字节 | 0 ~ 2^64-1 | |
int | 有 | 32位系统4字节,64位系统8字节 | 2^31 ~ 231-1,-263 ~ 2^63-1 | |
uint | 无 | 32位系统4字节,64位系统8字节 | 0 ~ 2^32-1,0 ~ 2^64-1 | |
rune | 有 | 与int32一样 | 2^31 ~ 2^31-1 | 与int32一样,表示一个unicode码,存储中文字符用rune |
byte | 无 | 与uint8一样 | 0 ~ 255 | 与uint8一样,要存储字符时选择byte |
golang中整型默认声明为int型
// 查看数据类型
var a1 = 100
fmt.Printf("a1的类型是 %T", a1)
// 查看数据类型和占用字节数
var a2 int8 = 100
fmt.Printf("a2的类型是 %T, 占用的字节数是 %d", a2, unsafe.Sizeof(a2))
类型 | 占用存储空间 | 数据范围 |
---|---|---|
单精度float32 | 4字节 | -3.403E38 ~ 3.403E38 |
双精度float64 | 8字节 | -1.798E308 ~ 1.798E308 |
golang中浮点型默认声明为float64,开发中推荐使用float64,精度更高
var b1 byte = 'a'
// 如果直接输出byte,得到的是字符对应的ASCII码
fmt.Println("b1=", b1)
// 如果希望输出字符,需要使用格式化输出
fmt.Printf("b1=%c", b1)
bool只能是true或者false,占1个字节
golang中采用的utf8编码,不用担心中文乱码问题;
字符串一般用双引号(“”),想输出代码块可以用反引号(``)
str1 := "abc\nabc"
fmt.Println(str1)
str2 := `
var b1 byte = 'a'
// 如果直接输出byte,得到的是字符对应的ASCII码
fmt.Println("b1=", b1)
// 如果希望输出字符,需要使用格式化输出
fmt.Printf("b1=%c", b1)
`
fmt.Println(str2)
当一个字符串很长,需要+拼接是,+必须放在上一行,否则会报错
str3 := "hello " + "world " +
"hello " + "world " +
"hello " + "world " +
"hello " + "world " +
"hello " + "world "
fmt.Println(str3)
数据类型 | 默认值 |
---|---|
整数类型 | 0 |
浮点类型 | 0 |
布尔类型 | false |
字符串类型 | “” |
golang在数据类型的转换需要显示转换,不能自动转换
var i int32 = 100
var m int64 = int64(i)
var n int8 = int8(i)
fmt.Printf("i=%d, m=%d, n=%d", i, m, n)
注意:被转换的是值,变量本身的数据类型并没有转换。上面的例子,转换完以后,i依然是int32
// 大范围转小范围,可能会溢出,但不会报错,结果和我们期望的不一样
var n1 int64 = 99999999
var n2 int8 = int8(n1)
fmt.Println(n2)
a := 100
b := 101.1
c := true
d := 'h'
// 第一种方式 fmt.Sprintf 转换
var str1 string = fmt.Sprintf("%d", a)
var str2 string = fmt.Sprintf("%f", b)
var str3 string = fmt.Sprintf("%t", c)
var str4 string = fmt.Sprintf("%c", d)
fmt.Printf("str1=%q str2=%q str3=%q str4=%q", str1, str2, str3, str4)
// 第二种方式 strconv函数转换
// 10 代表10进制
var str5 string = strconv.FormatInt(int64(a), 10)
// 'f' 代表格式; 10 代表保留10个小数位; 64 表示这个小数是float64
var str6 string = strconv.FormatFloat(b, 'f', 10, 64)
var str7 string = strconv.FormatBool(c)
fmt.Printf("str5=%q str6=%q str7=%q", str5, str6, str7)
// strconv.FormatInt 简写
var str8 string = strconv.Itoa(a)
fmt.Printf("str8=%q", str8)
str1 := "true"
// strconv.ParseBool(str)有两个返回值 (value bool, err error)
// 我们只需要获取value bool的值,所以用 _ 忽略error
a, _ := strconv.ParseBool(str1)
fmt.Printf("a=%t", a)
str2 := "1000"
// strconv.ParseInt(str)的返回值是int64和error
b, _ := strconv.ParseInt(str2, 10, 0)
fmt.Printf("b=%v", b)
str3 := "123.456"
// strconv.ParseFloat(str)的返回值是float64和error
c, _ := strconv.ParseFloat(str3, 64)
fmt.Printf("c=%v", c)
// 注意:如果转换失败了,会存储一个默认值
str4 := "hello"
var d int64 = 12
d, _ = strconv.ParseInt(str4, 10, 64)
// 输出结果为默认值0
fmt.Printf("d=%v", d)
func main() {
i := 10
// 获取i的地址
fmt.Println("i的地址=", &i)
// ptr是一个指针变量,类型是 *int (int型的指针)
// ptr存储的值是 &i,也就是i的地址
var ptr *int = &i
fmt.Printf("ptr=%v\n", ptr)
// ptr本身也有一个地址
fmt.Printf("ptr的地址=%v\n", &ptr)
// 获取ptr指向的值
fmt.Printf("ptr指向的值=%v\n", *ptr)
}
值类型:int系列、float系列、bool、string、数组、结构体(struct);
引用类型:指针、切片(slice)、map、管道(channel)、interface;
值类型变量直接存储值,内存在栈中分配;
引用类型变量存储的是地址,这个地址对应的空间存储的是值,内存在堆中分配,没有任何变量引用这个地址时,等待GC回收
注意事项:
注意:golang中没有三元运算符
+ - * / % ++ --
// 如果运算的都是整数,除法运算以后,结果也是整数,小数部分被截取掉
// 结果为2
fmt.Println(10 / 4)
// 结果还是2
var n1 float32 = 10 / 4
fmt.Println(n1)
// 如果希望保留小数部分,则需要有浮点数参与运算
var n2 float32 = 10.0 / 4
fmt.Println(n2)
// 取模计算公式 a % b = a - a / b * b
fmt.Println("10 % 3=", 10%3)
fmt.Println("-10 % 3=", -10%3)
fmt.Println("10 % -3=", 10%-3)
fmt.Println("-10 % -3=", -10%-3)
// ++ 和 --只能独立作为一行语句使用,不能放在表达式中使用
// 只有 后++ 和 后--; 没有 前++ 和 前--
== != > < >= <=
&& || !
= += -= *= /= %=
func main() {
// 两个变量 a 和 b,在不引入中间变量的情况下,交换 a 和 b的值
a := 10
b := 20
fmt.Printf("交换前 a=%d b=%d \n", a, b)
a = a + b
b = a - b // b = a + b - b => b = a
a = a - b // a = a + b - a
fmt.Printf("交换后 a=%d b=%d \n", a, b)
}
// 按位与& : 两位全为1,结果为1,否则为0
// 按位或| : 两位有一个为1,结果为1,否则为0
// 按位异或^ : 两位一个为0,一个为1,结果为1,否则为0
// 右移>> : 低位溢出,符号位不变,并用符号位补溢出的高位
// 左移<< :符号位不变,低位补0
对于有符号的而言:
二进制最高位是符号位:0表示整数,1表示负数
正数的原码、反码、补码都一样
负数的反码是原码的符号位不变,其他位取反
负数的补码是它的反码+1
1 => 原码[0000 0001] 反码[0000 0001] 补码[0000 0001]
-1 => 原码[1000 0001] 反码[1111 1110] 补码[1111 1111]
0的反码补码都是0
计算机运算的时候,都是以补码的方式来运算的
运算符
// 按位与& : 两位全为1,结果为1,否则为0
// 按位或| : 两位有一个为1,结果为1,否则为0
// 按位异或^ : 两位一个为0,一个为1,结果为1,否则为0
// 右移>> : 低位溢出,符号位不变,并用符号位补溢出的高位
// 左移<< :符号位不变,低位补0
对于有符号的而言:
二进制最高位是符号位:0表示整数,1表示负数
正数的原码、反码、补码都一样
负数的反码是原码的符号位不变,其他位取反
负数的补码是它的反码+1
1 => 原码[0000 0001] 反码[0000 0001] 补码[0000 0001]
-1 => 原码[1000 0001] 反码[1111 1110] 补码[1111 1111]
0的反码补码都是0
计算机运算的时候,都是以补码的方式来运算的
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!