本文对Go语言的基础语法和常用特性进行总结。
基础语法
首先看看第一段程序Hello! World长什么样子,代码如下:
package main
import "fmt"
func main() {
fmt.Println("Hello World")
}
变量
变量的声明、赋值与使用
package main
import "fmt"
func main(){
// 1.变量的声明
var age int
// 2.变量的赋值
age = 18
// 3.变量的使用
fmt.Println("age = ", age)
// 声明和赋值可以合成一句
var age2 int = 19
fmt.Println("age2 = ", age2)
// 不可以在赋值时给予不匹配的类型
// var age3 int = 3.14
}
在golang中变量有四种定义方式,以下包括全局变量的使用:
package main
import "fmt"
// 全局变量;定义在函数外
var n7 = 100
var n8 = 9.7
// 上面的全局变量写法比较麻烦,可以一次性声明
var (
n9 = 500
n10 = "netty"
)
func main(){
// 第一种:指定变量的类型并且赋值
var num int = 18
fmt.Println(num)
// 第二种:指定变量的类型,不赋值,使用默认值
var num2 int
fmt.Println(num2) // 0
// 第三种:如果没有写变量的类型,通过值来推导变量的类型
var name = "zjy"
fmt.Println(name)
// 第四种:省略var,使用 := 来声明并且赋值,不能写为 =
sex := "man"
fmt.Println(sex)
fmt.Println("--------------------")
// 声明多个变量
var n1,n2,n3 int
fmt.Println(n1,n2,n3)
var n4,name2,n5 = 100,"zjy",3.14
fmt.Println(n4,name2,n5)
// 声明多个变量的简写
n6,height := 100,3.45
fmt.Println(n6,height)
// 输出全局变量
fmt.Println(n7,n8,n9,n10)
}
数据类型
整数型
Golang程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型
浮点型
package main
import "fmt"
func main(){
// 定义浮点类型的数据
var num1 float32 = 3.14
fmt.Println("num1 = ",num1)
// 可以表示正浮点数也可以表示负浮点数
var num2 float32 = -3.14
fmt.Println("num2 = ",num2)
// 浮点数可以用十进制表示也可以用科学记数法表示形式,E大小写都可以
var num3 float32 = 314E-2
fmt.Println("num3 = ",num3)
var num4 float32 = 314e-2
fmt.Println("num4 = ",num4)
// 浮点数可能会有精度损失,通常用float64
var num5 float32 = 3.141592653
fmt.Println("num5 = ",num5)
var num6 float64 = 3.141592653
fmt.Println("num6 = ",num6)
// golang中的浮点数默认是float64类型
var num7 = 3.14
fmt.Printf("num7的数据类型是%T\n",num7)
}
字符型
字符型即char类型在golang中对应的是byte
package main
import "fmt"
func main(){
// 定义字符类型数据
var c1 byte = 'a'
fmt.Println("c1 = ",c1) // 97
var c2 byte = '0'
fmt.Println("c2 = ",c2) // 48
// 如果直接输出byte类型的数据,输出的是对应的字符
var c3 int = '中'
fmt.Println("c3 = ",c3) // 20013
// 字母、数字、符号都可以直接使用byte类型,底层都对应ASCII码值
// 汉字字符底层对应的是Unicode码值,使用byte类型会溢出,所以使用int类型
// 总结:Golang中的字符对应使用的是UTF-8编码(Unicode是对应的字符集,UTF-8是Unicode的其中一种实现)
var c4 byte = 'A'+19 // 想显示对应的字符,需要使用格式化输出
fmt.Printf("c4 = %c\n",c4) // T
}
golang中也提供string即字符串
package main
import "fmt"
func main() {
// 1.定义一个字符串
var s1 string = "hello"
fmt.Println(s1)
// 2.字符串是不可变的: 字符串一旦定义好,其中的字符的值不能改变
var s2 string = "abc"
fmt.Println(s2)
// 3.字符串的表示形式
// (1)如果字符串中没有特殊字符,字符串的表示形式用双引号
var s3 string = "hello"
fmt.Println(s3)
// (2)如果字符串中有特殊字符,字符串的表示形式用反引号
var s4 string =`hello\nworld`
fmt.Println(s4)
// 4.字符串的拼接
var s5 string = "hello" + "world"
s5 += "!"
fmt.Println(s5) // helloworld!
// 当一个字符串过长时,可以分行书写,+号必须在上一行的末尾
var s6 string = "hello" + "world" +
"hello" + "world" +
"hello" + "world"
fmt.Println(s6)
}
布尔类型
package main
import "fmt"
func main(){
// 测试布尔类型的数值
var b1 bool = true
fmt.Println("b1 = ",b1) // true
var b2 bool = false
fmt.Println("b2 = ",b2) // false
// 布尔类型不能参与数值运算,也不能与其他类型进行转换
var b3 bool = 5 < 9
fmt.Println("b3 = ",b3) // true
}
指针的使用
package main
import "fmt"
func main(){
var age int = 18
// &+变量名表示取地址
fmt.Println(&age)
// var表示声明一个变量
// ptr表示指针变量的名字
// ptr对应的类型是: *int(指向int类型的指针)
var ptr *int = &age
fmt.Println(ptr)
fmt.Println("ptr的地址是:",&ptr)
// 获取ptr指针指向的数据
fmt.Println("ptr指针指向的数据是:",*ptr)
}
运算符注意事项
package main
import "fmt"
func main(){
var a int = 10
a++
fmt.Println(a)
a--
fmt.Println(a)
// ++,--只能独立使用,不能参与运算
// var b int = a++ // 编译会报错
// ++,--只能写在变量的后面,不能写在变量的前面
// ++a // 编译会报错
}
分支结构
package main
import "fmt"
func main(){
//给出一个学生分数:
var score int = 87
//根据分数判断等级:
//switch后面是一个表达式,这个表达式的结果依次跟case进行比较,满足结果的话就执行冒号后面的代码。
//default是用来“兜底”的一个分支,其它case分支都不走的情况下就会走default分支
//default分支可以放在任意位置上,不一定非要放在最后。
switch score/10 {
case 10 :
fmt.Println("您的等级为A级")
case 9 :
fmt.Println("您的等级为A级")
case 8 :
fmt.Println("您的等级为B级")
case 7 :
fmt.Println("您的等级为C级")
case 6 :
fmt.Println("您的等级为D级")
// fallthrough //fallthrough语句可以执行满足条件的case的下一个case,是为了兼容C语言中的case设计的
case 5 :
fmt.Println("您的等级为E级")
case 1,2,3,4 : // case后面可以跟多个表达式,用逗号分隔
fmt.Println("您的等级为F级")
default:
fmt.Println("您的成绩有误")
}
}
循环结构
package main
import "fmt"
func main(){
//实现一个功能:求和: 1+2+3+4+5:
//求和:
//利用for循环来解决问题:
var sum int = 0
for i := 1; i <= 5; i++ {
sum += i
}
//输出结果:
fmt.Println(sum) //15
// for循环的语法格式:
// for 初始表达式; 布尔表达式(条件判断); 迭代因子 {
// 循环体;-->反复重复执行的内容
// }
// 注意:for的初始表达式 不能用var定义变量的形式,要用:=
//定义一个字符串:
var str string = "hello golang你好"
for i, value := range str {
fmt.Printf("索引为:%d,具体的值为:%c \n", i, value)
}
//对str进行遍历,遍历的每个结果的索引值被i接收,每个结果的具体数值被value接收
//遍历对字符进行遍历的
}
常用特性
函数
golang可以返回多个参数
func cal(num1 int,num2 int)(int,int){
var sum int = num1 + num2
var sub int = num1 - num2
return sum,sub
}
可以使用 _ 来忽略某个返回值
sum1,_ := cal(19,89)
init函数
init是golang中的初始化函数,可以用来进行一些初始化的操作,每一个源文件都可以包含一个init函数,该函数会在main函数执行前,被Go运行框架调用
匿名函数
golang支持匿名函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数
package main
import (
"fmt"
)
// 匿名函数全局调用
var add = func(num1 int, num2 int) int {
return num1 + num2
}
func main() {
// 定义匿名函数,定义的同时调用
result := func(num1 int, num2 int) int {
return num1 + num2
}(10, 20)
fmt.Println(result)
// 定义匿名函数,赋值给变量
f := func(num1 int, num2 int) int {
return num1 + num2
}
result = f(10, 20)
fmt.Println(result)
// 调用全局匿名函数
result = add(10, 20)
fmt.Println(result)
}
defer
在函数中,我们经常需要创建资源,为了在函数执行完毕后,及时的释放资源,我们可以使用defer关键字
func foo() int {
a, b := 3, 5
c := a + b
defer fmt.Println("111", c) // defer注册 会在函数结束前执行
fmt.Println(c)
// defer注册时会把相关的值拷贝进去,所以c的值不会改变
defer func() {
fmt.Println("333", c)
}()
c = 100
defer fmt.Println("222", c)
return c
}
切片
切片(slice)是golang中一种特有的数据类型
func main() {
// 切片的定义
arr := make([]int, 3, 5)
// 切片的赋值
arr[0], arr[1], arr[2] = 2, 7, 9
// 切片的追加
brr := append(arr, 8)
brr = append(brr, 8)
arr[0] = 4
fmt.Println(brr[0])
brr = append(brr, 8)
arr[1] = 5
fmt.Println(brr[1])
fmt.Println(len(brr), cap(brr))
fmt.Println(len(arr), cap(arr))
// 切片的遍历
for i, ele := range arr {
fmt.Printf("%p %p %d %d\n", &ele, &arr[i], ele, arr[i])
}
}