赞
踩
目录
大学时期的我一直纠结于编程语言的选择,直到我关注的一个博主 “英雄哪里出来” 他解答过这个问题。
原话我记不清了大概意思是不管哪种语言都会有 “很厉害或者很菜的人” ,最重要的是先学好一门语言(不管哪种),然后拥有能快速入门其他语言并应用起来的能力。
最近空闲时间我就看了Go的基础语法(先简单入了个门,Go也应用于游戏服务端,万一以后会用到呢)。
地址:Go安装包下载
下载完是一个安装包直接安装,使用安装包安装在系统变量的环境变量Path中会自动把Go环境配置好
用户变量的Path可能会自动配置到C盘,可以自己改一下
安装完成后测试
打开高级系统设置——》环境变量
在自己设置的GOPATH目录里新建三个文件夹
打开命令行窗口查看有没有配置好
开发工具可以下载GoLand或者VSCode(我用的VSCode)
【go】一、go语言vscode开发环境_vscode 运行go-CSDN博客
有些变量名重复我都注释掉了,可以打开注释自己练习一下
- package main
-
- import "fmt"
-
-
- //全局变量
- var name string = "李四"
-
-
- func main(){
- //fmt.Println("hello world!") //输出语句
- // var name string = "www" //定义变量
- // var age int = 23
- // fmt.Println(name)
- // fmt.Println(age)
- // var (
- // name1 string
- // age1 int
- // addr string
- // )
- // fmt.Println(name1,age1,addr)
- // name1 = "111"
- // age1 = 24
- // addr = "222"
- // fmt.Println(name1,age1,addr)
- // // := 自动推导数据类型
- // name3 := "www"
- // age3 := 23
- // fmt.Println(name3,age3)
- // fmt.Printf("%T,%T",name3,age3) //打印什么类型
-
- // var num int
- // num=100
- // fmt.Printf("num:%d,内存地址:%p",num,&num) //取地址符号 & num:100,内存地址:0xc00000a0b8
-
- /*变量交换*/
- // var a int = 100
- // var b int = 200
- // b,a = a,b //a,b的值互换
- // fmt.Println(a,b) //200 100
-
- // a,b := test()
- // fmt.Println(a,b)
-
- // c,_ := test() // _(匿名变量) 当不用第二个返回值时用 _ 接收
- // fmt.Println(c)
-
- /*局部变量*/
- // var name string = "李五"
- // fmt.Println(name) //优先打印局部变量
-
- /*常量*/
- // const URL string = "www.baidu.com" //显示定义(明确什么类型)
- // const URL2 = "www.baidu.com" //隐式定义(不明确类型)
- // const a,b,c = 3.14,"www",false
- /*
- iota,特殊常量,可以认为是一个可以被编译器修改的常量。
- iota是go语言的常量计数器iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次(iota 可理解为 const 语句块中的行索引)。
- iota 可以被用作枚举值
- */
- // const(
- // d = iota
- // e = iota
- // f = iota
- // )
- // fmt.Println(URL,URL2)
- // fmt.Println(a,b,c,d,e,f) //3.14 www false 0 1 2
-
- // const(
- // a = iota //0
- // b //1
- // c //2
- // d = "hahaha" //hahaha iota 3
- // e //hahaha iota 4
- // f = 100 //100 iota 5
- // g //100 iota 6
- // h = iota //iota 7
- // i //iota 8
- // )
- // fmt.Println(a,b,c,d,e,f,g,h,i) //0 1 2 hahaha hahaha 100 100 7 8
- }
-
- func test()(int,int){
- return 100,200
- }
- package main
-
- import "fmt"
-
- func main(){
- //定义一个整型
- var age int = 18
- fmt.Printf("%T,%d\n",age,age)
-
- //定义一个浮点型
- //默认保留六位小数
- var money float64 = 3.14
- fmt.Printf("%T,%f\n",money,money)
-
- /*
- int,18
- float64,3.140000
- */
-
- var num1 float32 = -123.0000901
- var num2 float64 = -123.0000901
- fmt.Println("num1 = ",num1,"num2 =",num2)
- //num1 = -123.00009 num2 = -123.0000901 float32内存空间不够精度丢失
- }
- package main
-
- import "fmt"
-
- func main(){
- var str string
- str = "hello,www"
- fmt.Printf("%T,%s\n",str,str)
-
- //单引号
- v1 := 'A'
- v2 := "A"
- fmt.Printf("%T,%s\n",v1,v1)
- fmt.Printf("%T,%d\n",v1,v1)
- fmt.Printf("%T,%s\n",v2,v2)
-
- /*
- string,hello,www
- int32,%!s(int32=65)
- int32,65
- string,A
- */
-
- //所有的中国字的编码表: GBK
- //全世界的编码表: Unicode编码表
-
- //字符串拼接
- fmt.Println("hello" + ",www")
-
- //转义字符
- fmt.Println("hello\",www") //hello",www
- }
- package main
-
- import "fmt"
-
- func main(){
-
- str := "hello,www"
- fmt.Println(str)
-
- // 获取字符串的长度 len
- fmt.Println("字符串的长度为:",len(str)) //字符串的长度为: 9
-
- // 获取指定的字节
- fmt.Println("字节打印:",str[0]) //输出结果为104对应'h'的ascii码
- fmt.Printf("%c",str[0]) //h
-
- // for
- for i := 0; i < len(str); i++{
- fmt.Printf("%c",str[i])
- }
-
- // for range 循环,遍历数组、切片...
- for i,v := range str{
- fmt.Print(i) //i表示下标
- fmt.Printf("%c",v) //v对应的字符
- }
- //0h1e2l3l4o5,6w7w8w
- }
在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值。由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显示的声明。
- package main
-
- import "fmt"
-
- func main(){
- a := 3 //int
- b := 5.0 //float64
- fmt.Printf("%T\n",a)
- fmt.Printf("%T\n",b)
-
- //将int类型的a转换为 float64 类型
- c := float64(a)
- d := int(b)
- fmt.Printf("%T\n",c)
- }
- package main
-
- import "fmt"
-
- func main(){
- var a int = 10
- var b int = 3
- //var c int
-
- //+ - * / % ++ --
- fmt.Println(a+b)
- fmt.Println(a-b)
- fmt.Println(a*b)
- fmt.Println(a%b)
- a++ // a = a+1
- fmt.Println(a)
- a-- // a = a-1
- fmt.Println(a)
- }
-
- 13
- 7
- 30
- 1
- 11
- 10
- package main
-
- import "fmt"
-
- func main(){
- var a int = 11
- var b int = 10
-
- //关系运算符
- fmt.Println(a==b)
- fmt.Println(a!=b)
- fmt.Println(a>b)
- fmt.Println(a<b)
- fmt.Println(a>=b)
- fmt.Println(a<=b)
-
- //判断if
- if a>b{
-
- }
- }
- false
- true
- true
- false
- true
- false
- package main
-
- import "fmt"
-
- func main(){
- var a bool = true
- var b bool = false
-
- // 逻辑 && 与
- if a==true && b==true{
- fmt.Println(a && b)
- }
- fmt.Println(a && b)
- // 逻辑 || 或 都为假才会返回假
- fmt.Println(a || b)
- //逻辑 ! 非
- fmt.Println(!a)
- }
- package main
-
- import "fmt"
-
- func main(){
-
- // 二进制 0 1 逢二进一
-
- // 位运算: 二进制上的 0 false 1 true
- // & 我和你 都为1 结果才为1
- // | 我或者你 有一个为1 结果才为1
- // ^ 不同为 1,相同为0
- // 60 二进制: 0011 1100
- // 13 二进制: 0000 1101
- //------------------------------
- // & : 0000 1100
- // | : 0011 1101
- // ^ : 0011 0001
- // >>: 1111 0000
- var a uint = 60
- var b uint = 13
- // 位运算
- var c uint = 0
-
- c = a&b // 位运算符&
- fmt.Println("%d,二进制%b",c,c) //12,二进制 1100
-
- c = a|b // 位运算符|
- fmt.Println("%d,二进制%b",c,c) //61,二进制 111101
-
- c = a^b
- fmt.Println("%d,二进制%b",c,c) //49,二进制 110001
-
- c = a << 2
- fmt.Println("%d,二进制%b",c,c) //240 二进制 1111 0000
-
- c = a >> 2
- fmt.Println("%d,二进制%b",c,c) //15 二进制 0000 1111
- }
- package main
-
- import "fmt"
-
- func main(){
- var a int = 21
- var b int
-
- // =赋值
- b = a // b = 21
- fmt.Println(b)
-
- // += b = a+b = 42
- b += a
- fmt.Println(b)
- }
- package main
-
- import "fmt"
-
- func main(){
-
- var x int
- var y float64
-
- // 定义了两个变量,想用键盘来录入这两个变量
- // fmt.Println() 打印并换行
- // fmt.Printf() 格式化输出
- // fmt.Print() 打印输出
- // fmt.Scanln() 换行接收输入
- // fmt.Scanf() 格式化输入
- // fmt.Scan() 接收输入
-
- fmt.Println("请输入两个数:1、整数,2、浮点数:")
-
- // 变量取地址 &变量 通过指针地址来操作变量
- fmt.Scanln(&x,&y) // 接收输入 Scan
-
- fmt.Scanln(&x,&y)
- fmt.Println("x:",x)
- fmt.Println("y:",y)
- }
程序的流程控制结构一共有三种:顺序结构,选择结构,循环结构
顺序结构:从上到下,逐行执行。默认的逻辑
:条件满足某些代码才会执行
- var a int = 15
- if a>20 {
- fmt.Println("a>20")
- }
- else if a>10{
- fmt.Println("a>10")
- }
- else{
- fmt.Println("a")
- }
- package main
-
- import "fmt"
-
- func main(){
- var score int = 60
-
- switch score {
- case 90:
- fmt.Println("A")
- case 80:
- fmt.Println("B")
- case 50,60,70:
- fmt.Println("C")
- default:
- fmt.Println("D")
- }
-
- switch {
- case false:
- fmt.Println("false")
- case true:
- fmt.Println("true")
- default:
- fmt.Println("其他")
- }
- }
fallthrough 贯穿;直通
switch 默认情况下匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough穿透case,使用 fallthrough 会强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true。
- package main
-
- import "fmt"
-
- func main(){
-
- a := false
- switch a {
- case false:
- fmt.Println("false")
- fallthrough //case穿透,不管下个条件满不满足都会执行(只判断fallthrough的下一个条件)
- case true:
- fmt.Println("true")
- default:
- fmt.Println("其他")
- }
-
- //输出结果
- //false
- //true
- }
:条件满足某些代码会被反复执行0-N次
- count := 5
- // for 条件的起始值;循环条件;控制变量自增或自减
- for i := 0; i < count; i++ {
- fmt.Println("----",i);
- }
-
-
- //break 跳出整个循环
- //continue 跳过本次循环
打印方阵练习:
- count := 5
- for i := 0; i < count; i++ {
- for j := 0;j < count;j++{
- fmt.Print("* ")
- }
- fmt.Println()
- }
打印九九乘法表:
- package main
-
- import "fmt"
-
- func main(){
- count := 9
- for i := 1; i <= count; i++ {
- for j := 1;j <= i;j++{
- fmt.Print(j,"*",i,"=",j*i," ")
- }
- fmt.Println()
- }
- }
- package main
-
- import "fmt"
-
- //func 函数名 (参数,参数...) (返回值类型){ 函数体 return 返回结果}
-
- func main(){
- printinfo()
- c := add(1,2)
- myprint(c)
- x,y := swap("aaa","bbb") //不想用y可以用匿名变量只接收一个返回值 x,_ := swap("aaa","bbb")
- fmt.Println(x,y)
- }
-
- //无参无返回值函数
- func printinfo(){
- fmt.Println("printinfo")
- }
-
- //有一个参数的函数
- func myprint(num int){
- fmt.Println(num)
- }
-
- //有两个参数一个返回值的函数
- func add(a,b int)(int){
- c := a+b
- return c
- }
-
- //多个返回值的函数
- func swap(x,y string)(string,string){
- return y,x
- }
-
- // max 两个数字比大小
- // 形式参数:定义函数时,用来接收外部传入数据的参数,就是形式参数
- // 实际参数:调用函数时,传给形参的实际数据叫做实际参数
- func max(num1,num2 int) int{
- var result int
- if num1 > num2 {
- result = num1
- } else {
- result = num2
- }
-
- //函数定义上有返回值,函数中必须有return
- return result
- }
注意事项:
- package main
-
- import "fmt"
-
- func main(){
- getSum(1,2,3,4,5,6,7)
- }
-
-
- // ...可变参数
- func getSum(nums ...int){
-
- sum:=0
-
- for i := 0; i < len(nums); i++ {
- fmt.Println(nums[i])
- sum += nums[i]
- }
-
- fmt.Println("sum:",sum)
- }
-
-
- // 1
- // 2
- // 3
- // 4
- // 5
- // 6
- // 7
- // sum: 28
按照数据的存储特点分:
- package main
-
- import "fmt"
-
- func main(){
- //值传递:传递的是数据的副本,修改数据对原始数据无影响
- //值传递类型:基础类型、array、struct(结构体)
- //定义一个数组 [个数]类型
- arr := [4]int{1,2,3,4}
- fmt.Println(arr)
- //传递:arr2的数据是复制arr来的的,arr2并不影响arr
- update(arr)
- fmt.Println("调用后的数据",arr)
- }
-
- func update(arr2 [4]int){
-
- fmt.Println("arr2接收的数据:",arr2)
- arr2[0] = 100
- fmt.Println("arr2修改后的数据:",arr2)
- }
-
- // [1 2 3 4]
- // arr2接收的数据: [1 2 3 4]
- // arr2修改后的数据: [100 2 3 4]
- // 调用后的数据 [1 2 3 4]
变量在内存中是存放在一定的地址上的,修改变量实际是修改变量地址的内存
- package main
-
- import "fmt"
-
- func main(){
- //引用传递:传递的是数据的地址,导致多个变量指向同一块内存
- //切片,可以扩容的数组
- s1 := []int{1,2,3,4}
- fmt.Println("默认的数据",s1)
- update2(s1)
- fmt.Println("调用后的数据",s1)
- }
-
- func update2(s2 []int){
- fmt.Println("传递的数据",s2)
- s2[0] = 100
- fmt.Println("修改后的数据",s2)
- }
-
- // 默认的数据 [1 2 3 4]
- // 传递的数据 [1 2 3 4]
- // 修改后的数据 [100 2 3 4]
- // 调用后的数据 [100 2 3 4]
定义:一个函数自己调用自己
注意:递归函数要有一个出口,逐渐向出口靠近,没有出口就会形成死循环
- package main
-
- import "fmt"
- //求和:1,2,3,4,5
- func main(){
- sum := getSum(5)
- fmt.Println(sum)
- }
-
- func getSum(n int) int{
- if n == 1 {
- return 1
- }
- return getSum(n - 1) + n
- }
-
- //15
defer:推迟、延迟
在go语言中,使用defer关键字来延迟一个函数或者方法的执行
- package main
- import "fmt"
- func main(){
- f("1")
- fmt.Println("2")
- defer f("3") //会被延迟到最后执行
- fmt.Println("4")
- }
-
- func f(s string){
- fmt.Println(s)
- }
-
- // 1
- // 2
- // 4
- // 3
defer函数或者方法:一个函数或方法的执行被延迟了
- package main
- import "fmt"
- func main(){
- f("1")
- fmt.Println("2")
- defer f("3") //会被延迟到最后执行
- fmt.Println("4")
- defer f("5") //会被延迟到最后执行
- fmt.Println("6")
- defer f("7") //会被延迟到最后执行
- fmt.Println("8")
- }
-
- func f(s string){
- fmt.Println(s)
- }
-
- // 1
- // 2
- // 4
- // 6
- // 8
- // 7
- // 5
- // 3
- package main
- import "fmt"
- func main(){
- a := 10
- fmt.Println("a=",a)
- defer f(a)
- a++
- fmt.Println("end a=",a)
- }
-
- func f(s int){
- fmt.Println("函数里面的a:",s) //a在执行defer的时候就已经传递进来了
- }
-
- // a= 10
- // end a= 11
- // 函数里面的a: 10
defer的用法:
文件.open()
defer.close()
读或写
panic函数用于引发恐慌,导致程序中断执行
recover函数用于恢复程序的执行,recover()语法上要求必须在defer中执行
- package main
- import "fmt"
- func main(){
- //f() 如果加了括号就成了函数的调用
- //f 如果不加括号,函数就是一个变量
- fmt.Printf("%T",f) //func() 本身就是一个数据类型
- fmt.Printf("%T",10)
- fmt.Printf("%T","hello")
- fmt.Printf("%T",f1) // func(int, int)
- fmt.Printf("%T",f2) // func(int, int) int
-
-
- //定义函数类型的变量
- var f5 func(int, int)
- f5 = f1
- //给变量赋值然后尝试调用它
- f5(1,2) // 1 2
-
- //打印 f1 和 f5 的地址发现是一样的,f1 和 f5 指向同一块地址,是引用类型
- fmt.Println(f5) // 0x71b1a0
- fmt.Println(f1) // 0x71b1a0
- }
- func f(){
-
- }
-
- func f1(a,b int){
- fmt.Println(a,b)
- }
-
- func f2(a,b int) int {
- return 0
- }
-
- // func()
- // int
- // string
- // func(int, int)
- //func(int, int) int
- //1 2
- // 0x71b1a0
- // 0x71b1a0
函数在Go语言中是复合类型,可以看做是一种特殊的变量
函数名(): 调用返回结果
函数名(): 指向函数体的内存地址,一种特殊类型的指针变量
- package main
- import "fmt"
-
- //匿名函数
- func main(){
-
- f()
- f1 := f // 函数本身也是一个变量
- f1()
-
- //匿名函数
- f2 := func(){
- fmt.Println("我是f2函数")
- }
- f2()
-
- //匿名函数自己调用自己
- func(){
- fmt.Println("我是f3函数")
- }() //加()相当于直接调用函数
-
- //匿名函数可以传递参数
- func(a,b int){
- fmt.Println(a,b)
- fmt.Println("我是f4函数")
- }(1,2) //加()相当于直接调用函数
-
- //匿名函数可以有返回值
- r1 := func(a,b int) int {
- fmt.Println("我是f5函数")
- return a+b
- }(1,2) //加()相当于直接调用函数
- fmt.Println(r1)
- }
-
- func f(){
- fmt.Println("我是f函数")
- }
-
- // 我是f函数
- // 我是f函数
- // 我是f2函数
- // 我是f3函数
- // 1 2
- // 我是f4函数
- // 我是f5函数
- // 3
高阶函数: 根据go语言的数据类型的特点,可以将一个函数作为另外一个函数的参数。
fun1(),fun2()
将 fun1 函数作为 fun2 这个函数的参数
fun2函数: 就叫做高阶函数,接收了一个函数作为参数的函数
fun1函数: 就叫做回调函数,作为另外一个函数的参数
- package main
- import "fmt"
-
- func main(){
- r1 := add(1,2)
- fmt.Println(r1)
-
- r2 := oper(3,4,add)
- fmt.Println(r2)
-
- r3 := oper(8,4,sub)
- fmt.Println(r3)
-
- r4 := oper(8,4,func(a int,b int) int{
- if b == 0{
- fmt.Println("除数不能为0")
- return 0
- }
- return a/b
- })
- fmt.Println(r4)
- }
-
- //高阶函数: 可以接收一个函数作为参数
- func oper(a,b int,fun func(int,int) int) int{
- r := fun(a,b)
- return r
- }
-
- func add(a,b int) int{
- return a+b
- }
-
- func sub(a,b int) int{
- return a-b
- }
-
- // 3
- // 7
- // 4
- // 2
- package main
- import "fmt"
-
- /*
- 一个外层函数中,有内层函效,该内层函数中,会操作外层函数的局部变量。
- 并且该外层函数的返回值就是这个内层函数。
- 这个内层函数和外层函数的局部变量,统称为闭包结构。
- */
-
- /*
- 局部变量的生命周期就会发生改变,正常的局部变量会随着函数的调用而创建,随着函数的
- 结束而销毁,但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁,因为内层函数还在继续使用。
- */
- func main(){
- r1 := increment()
- fmt.Println(r1)
-
- v1 := r1()
- fmt.Println(v1)
-
- v2 := r1()
- fmt.Println(v2)
-
- fmt.Println(r1())
- fmt.Println(r1())
- fmt.Println(r1())
-
- //定义r2
- r2 := increment()
- v3 := r2()
- fmt.Println(v3)
- fmt.Println(r1())
- fmt.Println(r2())
- }
-
- // 自增
- func increment() func() int {
- // 局部变量i
- i := 0
- // 定义一个匿名函数,给变量自增并返回
- fun := func() int { // 内层函数,没有执行的
- i++
- return i
- }
- return fun
- }
-
- // 0xa398a0
- // 1
- // 2
- // 3
- // 4
- // 5
- // 1
- // 6
- // 2
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。