go基础

go 语言基础

1 开发环境

1. go安装包

https://golang.google.cn/dl/

2. go的开发IDE

https://www.jetbrains.com

直接下一步,它会自动将go的环境添加到全局环境

注意:

  • goland创建项目,选择go 的安装路径(默认是自动选中)

  • gopath: 所有的代码必须放在这个路径下的src文件夹下,否则无法执行,默认创建到用户目录下的go文件夹,所有的系统都是一样的

  • 取消掉 index entire gopath,否则默认将路径加到全局环境

  • 路径和文件都不要出现中文

go的常用命令

go version

go env # go的环境变量
       """
   	set GO111MODULE= 空的,现在没有使用model模式
   	set GOPATH=C:\Users\小子\go 代码存放的路径
   	set GOROOT=E:\go  go sdk安装的路径
       """
------------------------------------------------
go build # 编译型语言,需要先编译在执行,编译成可执行文件,执行可执行文件

go run #编译并执行,开发阶段用,两步并做一步

go get # 下载并安装依赖,相当于pip和npm

go fmt # 自动格式化代码

这些是需要记住的

2. 第一个hello,world!

vscode版本


# 1 写出go函数
package main // 声明包名, 包名是main 每一个文件都属于某一个包

import "fmt"  // 导入包,内置包

func main() { // 定义一个main函数
	fmt.Println("hello,world!!") // 打印函数==print()
}
// 单行注释

/*
多行注释
 */
# 2. 在控制台执行 go build
	C:\Users\小子\go\src\day01>go build s1.go

# 3. 在控制台执行编译的go.exe
    C:\Users\小子\go\src\day01>s1.exe
    hello,world!!
	
# 或者 go run s1.go 编译并执行 

go 的注释
// 单行注释

/*
多行注释
 */

goland版本:直接右键执行

入口

  • go 所有的编译型语言运行都要有一个入口

  • go的入口是main包下的main()函数

  • main包下不可以有多个main函数

  • 当你创建多个go文件可以写main函数,因为设置的是以file执行,不是以项目来执行

3. 变量

3.1 定义变量的方式

方式一全定义:

  • var 关键字 变量名 变量类型 = 变量值
  • 在go中,变量定义了必须使用,如果不适应会报错
package main

import "fmt"

func main() {
	
	// var 关键字 变量名 变量类型 = 变量值
	var age int = 10 // 在go中,变量定义了必须使用,如果不适应会报错
	fmt.Println(age)
}

方式二: 类型推导,类型不用写

package main

import "fmt"

func main() {

	// 2 定义变量的第二种方式(类型推导,类型不用写)
	var age = 10
	var name = "lqz"
	fmt.Println(name) // 打印并换行
	fmt.Println(age) // 打印不换行
	fmt.Printf("%T", age) // 查看变量类型
	// 总结: 变量类型一旦确定,不能改变 变量不能重复使用


	// 3 定义变量的第三种方式(简略声明,类型和var都不写)
	a:=10
	fmt.Println(a)

}

方式三: 类型推导,类型不用写

package main

import "fmt"

func main() {
	// 3 定义变量的第三种方式(简略声明,类型和var都不写)
	a:=10
	fmt.Println(a)

}

3.2 声明多个变量

package main

import "fmt"

func main() {
	var width, height = 100, 50 // 方式一
	width, height := 100, 50 // 方式二
    var  (
		name = "zzzz"
		age = 29
		height int

	) // 方式三
	fmt.Println(width, height)

}

小坑

	var a int =10
	//var b =99
	b,a:=99,100    //这个不报错,我们觉得是重复定义,冒号左侧,只要有一个没有定义过的变量,就可以
	fmt.Println(b)
	fmt.Print(a)

总结:

  • 变量类型在定义阶段一旦确定,不能改变

  • 变量不能重复使用

3.3 变量命名规范

变量命名规范
	-变量命令建议用驼峰,(大小写有特殊意义)
	-go文件命名建议用 下划线
    - 一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母、数字或下划线
    -大写字母和小写字母是不同的:Name和name是两个不同的变量
    -关键字和保留字都不建议用作变量名

关键字

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

保留字

内建常量: true false iota nil
内建类型:  int int8 int16 int32 int64
          uint uint8 uint16 uint32 uint64 uintptr
          float32 float64 complex128 complex64
          bool byte rune string error

内建函数: make len cap new append copy close delete
          complex real imag
          panic recover

4 类型

整型:

  • 有符号整形
    • int:在32位机器是int32,在64位机器是int64

    • int8:表示整数范围是:8个比特位,8个bit是1byte ,负数和0, 2的7次方-1 的范围

      var a int8 =127
      fmt.Println(a)
      a=127
      
    • int16 2的15次方减一

    • int32

    • int64

  • 无符号整型
    • uint8 2的8次方减一 定义一个人的年龄
    • uint16
    • uint32
    • uint64

浮点型(小数),表示小数点后长度多少位

  • float32
  • float64

复数

  • complex64

  • complex128

  • byte:是int8的别名

    var a byte = 'a' 
    fmt.Println(a)
    a =97
    
  • rune:是int32的别名

    var a rune = '你'
    fmt.Println(a)
    a = 20320 unicode编码
    

字符串

  • 双引号包裹

    package main
    
    import "fmt"
    
    func main() {
    	s := "lqz is np"
    	s1 := `lqz 
    			is
    			np
    			`
    	fmt.Println(s)
    	fmt.Println(s1)
    }
    
  • 反引号包裹 是声明格式返回的就是声明格式

    package main
    
    import "fmt"
    
    func main() {
    	s := "lqz is np"
    	s1 := `lqz 
    			is
    			np
    			`
    	fmt.Println(s)
    	fmt.Println(s1)
    }
    

    结果:

    lqz is np
    lqz 
    			is
    			np
    

    bool:就是True和False

    默认的数字类型0是false
    空字符串就false
    python所有的数据类型都带bool
    
    
    	var a int64
    	var s string
    	var b bool
    	fmt.Println(a,b,s)
    

    常量

    package main
    
    import "fmt"
    
    func main() {
    	//常量的定义 1
    	//const  变量名 变量类型 = 变量值
    	//const age int8 = 99
    	//fmt.Println(age)
    	//
    	////类型推导
    	//const ages = 99
    	//fmt.Println(ages)
    	//定义多个
    	const name, age = "zhangchen", 9
    	const (
    		names string = "laz"
    		ages = 9
    	)
    	fmt.Println(name, age, names, ages)
    	const (
    		s1 = iota
    		s2
    		s3
    		s4 = 99
    		s5 =iota
    	)
    	fmt.Println(s1)
    	fmt.Println(s2)
    	fmt.Println(s3)
    	fmt.Println(s4)
    	fmt.Println(s5)
    }
    
    # 结果
    zhangchen 9 laz 9
    0
    1
    2
    99
    4
    const 关键字不能改变
    

    函数

    形式:

    
    func名字(参数名 类型, 参数名 类型)(返回的类型,返回值类型){
    	函数内容
    	return 返回值1, 返回值2
    
    	}
    
    

    无返回值

    
     
    package main
    
    import "fmt"
    
    func main() {
    	//调用函数
    	add(2,3,"xxx") //这里的变量名不用写,直接填写数字,自动补齐
    }
    //1. 有参数无返回值(定义函数)
    func add(a int, b int, msg string)  {
    		fmt.Println(a+b)
    		fmt.Println(msg)
    }
    
    func add(a int, b int, msg string)可以简写成 add(a, b int, msg string)
    
  

  
  **有参数,有多个返回值**
  
  ``` go
  package main
  
  import "fmt"
  	a,b := add(3,4)
  	fmt.Println(a,b)
  	a,_ := add(3,4) // 下划线忽略一个返回值
  	fmt.Println(a)
  }
  
  func add(a,b int) (int,int) { // 这里有几个返回值,就写几个数据类型
  	return a + b, a*b
  
  }
  

命名返回值

package main

import "fmt"

func main() {

	a,b:= add(3,4)
	fmt.Println(a,b)

}

func add(a,b int)(c int,d int)  {
	c = a+b
	d = a*b
	return
}  // 这里的return 返回的的c,d可以不用写,默认返回这个值

5 匿名函数

写在函数内部,函数不能有名字


package main

import "fmt"

func main() {
	var a func()
	a = func() {
		fmt.Println("我是匿名函数")
	}

	a()
}

函数返回值为函数

package main

import "fmt"

func main() {

	  a := test()
	  fmt.Println(a) // 内存地址
	  a() //加括号调用
}

//函数返回值为函数
func test() func() {
	return func() {
		fmt.Println("我是匿名函数")
	}
}

函数返回值为函数,返回的函数带参数 ,类型只要有不一样的地方,就不是一个类型

package main

import "fmt"

func main() {
	a := test()
	a("xxx")
}

// 函数返回值为函数,返回的函数带参数 ,类型只要有不一样的地方,就不是一个类型
func test() func(msg string) {
	return func(msg string) {
		fmt.Println(msg)
	}
}

函数返回值为函数,返回的函数带参数,带返回值

package main

import "fmt"

func main() {
	a := test()
	fmt.Println(a(3,5))

}
//函数返回值为函数,返回的函数带参数,带返回值
func test() func(a,b int) int {
	return func(a,b int) int {
		return a+b
	}
}

函数参数为函数类型,返回值为带参数,返回值的函数类型

package main

import "fmt"

func main() {
	//a,b :=test(func() {
	//	fmt.Println("我是函数参数")
	//})(3,4)
	//
	f := func() {fmt.Println("我是函数参数")}
	f1 :=test(f)
	a,b := f1(3,4)
	fmt.Println(a,b)
 
}

// 函数参数为函数类型,返回值为带参数,返回值的函数类型
func test(f func()) func(a,b int) (int,int) {
		f()   
	return func(a,b int) (int,int){

		return a+b,a*b
	}
}


闭包函数

go的闭包函数有一个内存逃逸

package main

import "fmt"

func main() {

	// 闭包函数的使用
	a := test(19) // a 是闭包函数
	a()
    //装饰器(go中没有装饰器的语法糖)通过闭包函数来实现装饰器


}


// 闭包函数 1 定义在函数内部,2 对外部作用域有引用 只是多了一个一种函数传参的方式

func test(age int) func()  {
		a := func() {
			fmt.Println(age)
		}
		return                a
 }

给类型起别名

package main

import "fmt"

// 给类型起别名
type MyFunc func(a,b int) (int,string)
type Myint int
func main() {
	var a int=10
	var b Myint = 9 
	var a MyFunc =test()
	c,d :=a(1,3)
	fmt.Println(c,d)
}

func test()  MyFunc{
	return func(a, b int) (int, string) {
		fmt.Println("xxx")
		return 10,"ok"
	}

}

6 作用域

package main

import "fmt"

//在同一个包下,函数名不能重名
//var a int   //全局变量,全局有效,只要改了,就是改了
//func main() {
//	fmt.Println(a)  //0
//	a=19
//	fmt.Println(a) //19
//	test1()  //99
//	fmt.Println(a) //99
//}
//
//func test1()  {
//	a=99
//	fmt.Println(a)
//
//}


//变量的作用域范围

var a int   //全局变量,全局有效,只要改了,就是改了
func main() {
	var a int
	fmt.Println(a)  //0
	a=19
	fmt.Println(a) //19
	test1()  // 0
	fmt.Println(a) //19
}

func test1()  {
	fmt.Println(a)

}
posted @ 2021-01-20 21:51  小子,你摊上事了  阅读(54)  评论(0编辑  收藏  举报