Go语言入门
Hello,World
package main
import (
"fmt"
) //导入一个系统包fmt用于输出
func main() {
fmt.Println("Hello,World!") //输出
}
变量
变量的定义
定义变量的方式与Java不同,在Go中采用
var 变量名 变量类型 =
行尾不需要分号
例如:
var a string = "Hello,World!"
fmt.Println(a) //Hello,World!
fmt.Printf("a的类型是:%T\n", a) //a的类型是:string
也可以不定义类型,go会根据值自动识别
var b = "What's up!" //也可以不写明变量类型,go会自动识别
var c = 123
var d = 123.123
fmt.Println(b) //What's up!
fmt.Println(c) //123
fmt.Println(d) //123.123
fmt.Printf("b的类型是:%T\n", b) //b的类型是:string
fmt.Printf("c的类型是:%T\n", c) //c的类型是:int
fmt.Printf("d的类型是:%T\n", d) //d的类型是:float64
还可以通过简写的方式定义变量,同样会根据值自动推导变量的类型
a := 123
b := "123"
c := 123.123
Go语言还可以批量定义变量,并且变量如果未赋值,那么就会赋默认值
var a, b, c int
var (
d string
e float64
)
fmt.Println(a) //0
fmt.Println(b) //0
fmt.Println(c) //0
fmt.Println(d) //
fmt.Println(e) //0
fmt.Printf("a的类型是:%T\n", a) //a的类型是:int
fmt.Printf("b的类型是:%T\n", b) //b的类型是:int
fmt.Printf("c的类型是:%T\n", c) //c的类型是:int
fmt.Printf("d的类型是:%T\n", d) //d的类型是:string
fmt.Printf("e的类型是:%T\n", e) //e的类型是:float64
Go语言中可以使用取地址符&
打印变量的内存地址
fmt.Printf("a的值为:%d,a的类型是:%T,a的内存地址为:%p\n", a, a, &a) //a的值为:123,a的类型是:int,a的内存地址为:0xc0000aa058
变量的交换
在其他语言中,变量交换是非常麻烦的,比如java
int a = 10;
int b = 20;
int temp = 0;
temp = a;
a = b;
b = temp;
然而在Go语言中进行变量的交换是非常方便的
a := 888
b := 666
b, a = a, b
fmt.Println(a, b) //666 888
比较变量的内存地址会发现变量交换是值的交换,变量内存地址并未改变
a := 888
b := 666
fmt.Printf("a的值为 %d,a的内存地址为%p\n", a, &a)
fmt.Printf("b的值为 %d,b的内存地址为%p\n", b, &b)
//交换
b, a = a, b
fmt.Printf("a的值为 %d,a的内存地址为%p\n", a, &a)
fmt.Printf("b的值为 %d,b的内存地址为%p\n", b, &b)
a的值为 888,a的内存地址为0xc0000180b8
b的值为 666,b的内存地址为0xc0000180d0
a的值为 666,a的内存地址为0xc0000180b8
b的值为 888,b的内存地址为0xc0000180d0
匿名变量
匿名变量 _
是一个只写变量,你不能从这个变量获取值。这是因为在 Go 语言中,匿名变量并不是一个真正的变量,而是一个特殊的标识符,编译器会将 _
中的值直接抛弃,它不能获取变量的值,也不能对其进行赋值,只能在接受值时使用。
在Go中匿名变量用来处理我们想要忽略的返回值。它作为一个特殊的变量,用于接收不需要的值。当函数或方法在返回多个值时非常有用。有时候,我们可能只对其中一部分返回值感兴趣,不需要全部返回值。在这种情况下,我们可以使用匿名变量 _ 来接收那些我们不关心的值。
注意:因为Go语言对于变量的定义是有严格的要求的,如果一个变量定义之后没有被使用,那么就会报错。
func divide(a, b int) (quotient, remainder int) {
quotient = a / b
remainder = a % b
return
}
func main() {
_, remainder := divide(10, 3)
fmt.Println(remainder) // 输出:1
}
常量
在 Go 语言中,常量使用 const
关键字进行定义,一个基本的定义形式如下:
const constantName string = value
const constantName = value //也可以简写,go会自动判断类型
这里 constantName
就是你想要定义的常量的名称,value
是该常量的值。
示例:
const Pi = 3.14159
在 Go 中,可以定义布尔、数字和字符串类型的常量。
const a,b,c = "haha",12,false //批量定义
此外,还可以使用 const
块来定义多个常量,例如:
const (
StatusOK = 200
StatusNotFound = 404
)
上述定义中,StatusOK
和 StatusNotFound
都是常量,它们的值分别为 200 和 404。
需要注意的是,Go 语言中的常量在定义时必须被赋值,并且一旦被定义,其值就不能改变,否则会在编译期间报错。
iota
在Go语言中,iota
是一个预定义的标识符,用于枚举常量。它可以被认为是一个自增的枚举器,每次使用它时,它都会自动递增。
当我们定义一个枚举类型时,我们可以使用iota
来为每个常量分配唯一的值。在枚举列表中,第一个常量的值为0,每个后续常量的值都会自动递增1。例如:
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
在上面的代码中,Sunday
的值为0,Monday
的值为1,以此类推。由于后续常量的值都是通过iota
自动递增得到的,因此只需要为第一个常量显式地指定值。
iota
还可以用于生成一系列相关的常量值。例如:
const (
_ = iota // 忽略第一个值
KB = 1 << (10 * iota) // 1024
MB // 1048576
GB // 1073741824
TB // 1099511627776
)
在上面的代码中,_
表示忽略第一个值,这是因为我们只需要使用iota
生成后续的常量值。KB
的值为1左移10位,即1024,MB
的值为1左移20位,即1048576,以此类推。
注意:使用iota时,如果第一个常量使用了iota,那么后面定义的常量会被后续常量按照一定规则赋值,比如f=12345,那么g也是12345,并且iota的递增并未停止,当再次使用iota定义h时,h会接上iota的顺序7,iota的自增计数只在当前const范围内,如果在下方新建一个const,那么iota仍然从0开始自增。
const (
a = iota //0
b //1
c //2
d = "第三" //第三(iota仍然自增此时为3)
e //第三(iota仍然自增此时为4)
f = 12345 //12345(iota仍然自增此时为5)
g //12345(iota仍然自增此时为6)
h = iota //7
i //8
)
const(
j = iota //0
)
//0 1 2 第三 第三 12345 12345 7 8
fmt.Println(a, b, c, d, e, f, g, h, i)
常用数据类型
数值类型
-
整数类型:
int
:根据平台决定长度,通常为 32 位或 64 位。例如,在 64 位平台上,int
的取值范围是 − 2 63 −2^{63} −263 到 2 63 − 1 2^{63} -1 263−1。int8
:8 位有符号整数,取值范围为 − 2 7 −2^{7} −27到 2 7 − 1 2^{7} -1 27−1。int16
:16 位有符号整数,取值范围为 − 2 15 −2^{15} −215到 2 15 − 1 2^{15} -1 215−1。int32
:32 位有符号整数,取值范围为 − 2 31 −2^{31} −231到 2 31 − 1 2^{31} -1 231−1。int64
:64 位有符号整数,取值范围为 − 2 63 −2^{63} −263到 2 63 − 1 2^{63} -1 263−1。uint
:根据平台决定长度,通常为 32 位或 64 位,表示无符号整数。例如,在 64 位平台上,uint
的取值范围是 0 0 0到 2 63 − 1 2^{63} -1 263−1。uint8
:8 位无符号整数,取值范围为 0 0 0到 2 8 − 1 2^{8} -1 28−1。uint16
:16 位无符号整数,取值范围为 0 0 0到 2 16 − 1 2^{16} -1 216−1。uint32
:32 位无符号整数,取值范围为 0 0 0到 2 32 − 1 2^{32} -1 232−1。uint64
:64 位无符号整数,取值范围为 0 0 0到 2 64 − 1 2^{64} -1 264−1。
-
浮点数类型:
float32
:32 位浮点数,有效位数约为 7 位。它的取值范围大约是 − 3.4 × 1 0 38 −3.4×10^{38} −3.4×1038 到 3.4 × 1 0 38 3.4×10^{38} 3.4×1038。float64
(或简写为float
):64 位浮点数,有效位数约为 15 位。它的取值范围大约是 − 1.8 × 1 0 308 −1.8×10^{308} −1.8×10308 到 1.8 × 1 0 308 1.8×10^{308} 1.8×10308。
浮点数类型在通过
%.1f
这种方式限定输出小数位数的时候,并不是按照四舍五入的方式进行的,而是五舍六入var a float32 = 1.19 var b float32 = 1.16 var c float32 = 1.15 fmt.Printf("%.1f\n", a)//1.2 fmt.Printf("%.1f\n", b)//1.2 fmt.Printf("%.1f", c)//1.1
需要注意的是,这里的二进制位数并不是数据类型在内存中所占用的实际位数,而是数据类型的取值范围所对应的二进制位数。例如,int8
在内存中实际占用 8 位,但其取值范围对应的二进制位数是 7 位。
布尔类型
在 Go 语言中,布尔类型用于表示真假值。布尔类型的关键字是 bool
,它只有两个可能的取值:true
和 false
。
定义布尔变量的方式如下:
var variableName bool = true //false
布尔类型的默认值是 false
,即如果没有显式地给布尔变量赋值,它将默认为 false
。
需要注意的是,Go 语言是强类型语言,布尔类型不能与其他类型进行混合运算。也就是说,不能将布尔值与整数或字符串进行直接比较或运算,这样的操作是非法的。
字符串类型
在Go语言中,字符串类型使用""
双引号括起来标识,比如
var str string = "nihao"
字符类型
Go语言中的字符类型实际上是一个整数类型,用于表示Unicode字符。字符串类型使用''
单引号括起来标识,比如
var s rune = 'A'
var a int = int(c)
数据类型转换
在Go语言中,可以使用类型转换操作符将一个类型的值转换为另一个类型。类型转换的语法为:T(v),其中T表示目标类型,v表示待转换的值。
Go语言的类型转换有以下几个特点:
- 类型转换只能在两个相互兼容的类型之间进行,不能将不兼容的类型进行直接转换。例如,不能将字符串直接转换为整数类型。
- 类型转换是一种显式的操作,需要明确指定目标类型。如果目标类型与源类型之间存在兼容关系,那么类型转换是安全的,否则将会产生编译错误。
- 在进行类型转换时,可能会发生数据丢失或溢出的情况。这是因为类型转换可能会改变值的表示方式或大小。因此,在进行类型转换时需要谨慎,确保不会导致数据丢失或溢出。
- 不能将一个非兼容的类型转换为另一个非兼容的类型。例如,不能将一个结构体直接转换为数组类型。
下面是一些类型转换的示例:
var a int = 10
var b float64 = float64(a) // 将整数类型转换为浮点数类型
fmt.Printf("%f\n", b)//10.000000
var x float32 = 3.14
var y int = int(x) // 将浮点数类型转换为整数类型,小数部分将被截断
fmt.Printf("%d\n", y)//3
var str string = "123"
var num, _ = strconv.Atoi(str) // 将字符串类型转换为整数类型,使用strconv包中的函数进行转换,用_接受不需要使用的参数
fmt.Printf("%d", num)//123
需要注意的是,对于不同数字类型之间的转换,可以使用类型转换操作符进行直接转换。对于字符串和数字类型之间的转换,需要使用strconv包提供的函数进行转换。确保在进行类型转换时处理错误,以避免潜在的运行时错误。
运算符
在Go语言中,常见的运算符包括以下几种:
-
算术运算符:用于执行基本的数学运算,如加法、减法、乘法和除法。
- 加法运算符(+):用于将两个数值相加。
- 减法运算符(-):用于将一个数值减去另一个数值。
- 乘法运算符(*):用于将两个数值相乘。
- 除法运算符(/):用于将一个数值除以另一个数值。
- 取模运算符(%):用于获取两个数值相除后的余数。
// 算术运算符 a := 10 b := 3 fmt.Println(a + b) // 输出:13 fmt.Println(a - b) // 输出:7 fmt.Println(a * b) // 输出:30 fmt.Println(a / b) // 输出:3 fmt.Println(a % b) // 输出:1
-
关系运算符:用于比较两个数值之间的关系,返回布尔值(true或false)。
- 相等运算符(==):用于判断两个数值是否相等。
- 不等运算符(!=):用于判断两个数值是否不相等。
- 大于运算符(>):用于判断一个数值是否大于另一个数值。
- 小于运算符(<):用于判断一个数值是否小于另一个数值。
- 大于等于运算符(>=):用于判断一个数值是否大于或等于另一个数值。
- 小于等于运算符(<=):用于判断一个数值是否小于或等于另一个数值。
// 关系运算符 a := 10 b := 3 fmt.Println(a == b) // 输出:false fmt.Println(a != b) // 输出:true fmt.Println(a > b) // 输出:true fmt.Println(a < b) // 输出:false
-
逻辑运算符:用于执行逻辑操作,如与、或和非。
- 与运算符(&&):用于同时判断两个条件是否为真。
- 或运算符(||):用于判断两个条件中至少有一个为真。
- 非运算符(!):用于取反一个条件的结果。
// 逻辑运算符 c := true d := false fmt.Println(c && d) // 输出:false fmt.Println(c || d) // 输出:true fmt.Println(!c) // 输出:false
-
位运算符:用于对整数类型的数值进行位操作。
- 按位与运算符(&):用于对两个数值的每个位执行与操作。
- 按位或运算符(|):用于对两个数值的每个位执行或操作。
- 按位异或运算符(^):用于对两个数值的每个位执行异或操作。
- 左移运算符(<<):将一个数值的每个位向左移动指定的位数。
- 右移运算符(>>):将一个数值的每个位向右移动指定的位数。
// 位运算符 e := 5 // 二进制表示:101 f := 3 // 二进制表示:011 fmt.Println(e & f) // 输出:1(二进制表示:001) fmt.Println(e | f) // 输出:7(二进制表示:111) fmt.Println(e ^ f) // 输出:6(二进制表示:110) fmt.Println(e << 2) // 输出:20(二进制表示:10100) fmt.Println(e >> 1) // 输出:2(二进制表示:10)
-
赋值运算符:用于将一个值赋给变量。
- 简单赋值运算符(=):用于将右侧的值赋给左侧的变量。
- 复合赋值运算符(例如+=、-=、*=、/=等):先执行一个运算,然后将结果赋给左侧的变量。
// 赋值运算符 g := 10 g += 5 fmt.Println(g) // 输出:15
-
其他运算符:包括取地址运算符(&)、取值运算符(*)等,用于获取变量的地址或通过指针访问变量的值。
// 其他运算符 h := 10 fmt.Println(&h) // 输出:h的内存地址0xc000018190 i := &h fmt.Println(*i) // 输出:h的值10
获取键盘输入
在Go语言中,可以使用fmt
包的Scan
函数来获取键盘的输入。下面是一个简单的示例:
package main
import "fmt"
func main() {
var input string
fmt.Print("请输入内容:")
fmt.Scan(&input)
fmt.Println("你输入的内容是:", input)
}
在上面的例子中,首先创建了一个变量input
用于存储用户的输入内容。然后使用fmt.Scan
函数来获取用户的输入,并将输入的内容存储到input
变量中。最后使用fmt.Println
函数将输入的内容输出到控制台。
运行程序后,它会提示你输入内容。你可以在命令行中输入任意内容,然后按下回车键确认输入。程序将读取你的输入并输出到控制台上。
需要注意的是,fmt.Scan
函数会根据空格或换行符来分隔输入的内容。如果你想获取多个输入,可以使用多个变量,如fmt.Scan(&var1, &var2)
。每个变量对应一个输入内容。
另外,如果你需要将输入其他类型,比如整数或浮点数,可以使用fmt.Scanf
函数来指定输入的格式。例如,fmt.Scanf("%d", &num)
将输入解析为整数并存储到num
变量中。
var a int
var b float64
fmt.Print("请输入内容:")
fmt.Scanf("%d %f", &a, &b)//请输入内容:232 4334.13221
fmt.Printf("你输入的内容是:%T,a=%d\n", a, a) //你输入的内容是:int,a=232
fmt.Printf("你输入的内容是:%T,b=%f\n", b, b) //你输入的内容是:float64,b=4334.132210
特殊字符
转义字符
转义字符 | 作用 |
---|---|
\n | 换行 |
\r | 回车 |
\t | 制表符 |
\b | 退格 |
\f | 换页 |
\ | 反斜杠 |
指定输出格式
在Go语言中,格式化字符串中的%
字符是用于指定输出格式的特殊字符。以下是几种常见的%
字符及其含义:
%d
:用十进制整数格式打印。%x
、%X
:用十六进制格式打印,其中%x
表示小写字母,%X
表示大写字母。%o
:用八进制格式打印。%b
:用二进制格式打印。%f
、%e
、%E
:用浮点数格式打印,其中%f
表示标准的浮点数,%e
和%E
表示科学计数法。%s
、%q
:用字符串格式打印,其中%s
表示原始字符串,%q
表示带有双引号的字符串。%t
:用布尔值格式打印。%p
:打印指针地址。%v
:根据值的类型自动选择合适的格式进行打印。%T
:打印值的类型。
除了上述常见的格式化选项外,还有一些其他的格式化选项,例如%c
用于打印字符,%U
用于打印Unicode码点等。