20200324 go基本语法
目录
昨日回顾
go介绍
web框架 beego 中国人写的 gin 外国人 + gorm
开发环境搭建(go开发包,goland)
goland: 注册码都是通用的 http://idea.medeming.com/jets/
// 导入的包是从goroot与gopath中找的,找不到就报错
goroot 开发包安装路径
gopath 代码存放的位置(你写的代码,第三方包)
配了个path: 开发包的安装路径 /bin 添加进来了 go.exe
代码
第一行 package main main包,整个程序的入口,以后只有一个main包下的main函数
注释
// /* */
变量定义
先定义在使用 三种方式
定义了必须使用,否则报错
三种方式
- var a int=11
- var a=10
- a := 10
一门语言如果函数可以赋值给变量,函数就叫头等函数/一等公民
python是动态强类型的解释型语言
go是静态强类型的编译型语言
类型
- 数字
- 字符串
- 布尔
常量:
const a int=10
补充
go中有25个关键字
37个保留字: 内建的变量,数据和函数
变量定义推荐使用驼峰体
go文件命名,推荐使用下划线
go语法
函数
package main
// 这个位置不能写逻辑代码,只能定义变量与常量
// 定义函数
func main(){
}
1. 函数定义
基础定义
放在main函数的前后都可以
func关键字 函数名 (参数1 类型,参数2 类型){
函数体内容
}
带参数的函数
func main(){
test(1,2)
}
func test(a int,b int) {
fmt.Println(a+b)
}
两个参数类型相同可以省略
func test(a ,b int,c string) { //a,b是int,c是string
fmt.Println(a+b)
}
带返回值
必须需要指定返回值的类型
func main(){
var a int = test(1,2)
// a := test(1,2)
}
func test(a ,b int) int { // int指定返回值的类型
return a+b
}
多返回值
// python中可以用一个值来接受,go必须有多值接受多个
func main(){
a,b,c :=test(2,4)
fmt.Println(a,b,c) // 这个函数可以接受任意长度的参数
}
func test(a ,b int) (int,int,string) { // 加()进行返回多值
return a+b,a*b,"ok"
}
2. 可变长参数
不接收_
func main(){
a,_,c :=test(2,4) // 不接收,使用 _
fmt.Println(a,c) // 这个函数可以接受任意长度的参数
// fmt.Println(_) _ 并不是参数,不能打印
}
可变长...
func main(){
test(1,2,3) // 可以传任意长度
}
func test(a ...int) {
fmt.Println(a)
}
go只有位置参数,没有关键字参数一说,也没有默认参数
3. interface接口
所有类型的鼻祖,int, string, float32都属于interface类型
4. 匿名函数
没有名字的函数,定义在函数内部
func main(){
test()
}
// 1. 直接加括号执行
func test() {
// 函数内部不能定义有名的函数,只能定义匿名函数
func () {
fmt.Println('我是匿名函数')
} () // 匿名函数加括号执行
}
// 2. 赋值给一个变量再执行
func test() {
// var a func() 指定类型赋值
a := func () {
fmt.Println('我是匿名函数')
}
a()
fmt.Printf("%T",a) // 打印a的类型是func()
}
5. 函数的类型
函数的参数和返回值,都是类型的一部分,不是同一个类型
func main(){
// 定义一个
}
func myfunc(a,b int){
fmt.Println(a+b)
}
6. 闭包
定义在函数内部,对外部作用域有引用.
func main(){
// 定义一个a 是 函数类型
var a func() = test()
a()
}
1.基础的函数类型
func test() func(){
// 只是一个内层函数
a:=func(){
fmt.Println("我是内层函数")
}
return a
}
2. 如果内层函数有参数
func test() func(x,y int){ // 指定返回值的类型加上参数的返回值类型
a:= func(x,y int){ //函数的参数也是类型的一部分,所以不能返回值是func
fmt.Println("我是内层函数")
}
return a
}
3.内层函数带返回值
func test() func(x,y int)string{ //这里也必须指定
a:= func(x,y int)string{ // 内层函数的返回值必须指定类型
fmt.Println("我是内层函数")
return "我是内层函数的返回值"
}
return a
}
闭包函数 (就是多了一种函数传参的方式)
func main(){
a := test(2,3)
a() //函数不需要再传参了,它引用了外部作用域的参数
}
func test(x,y int) func() {
// 只是一个内层函数
a:= func(){
fmt.Println(x+y)
}
return a
}
可以用go实现装饰器,但是没有语法糖
7. 给函数的类型重命名
func main(){
test()
}
// 函数类型重命名
type myfunc func(z int)int
// func test(x,y int) func(z int)int {
func test(x,y int) myfunc {
// 只是一个内层函数
a:= func(z int)int{
fmt.Println(x+y+z)
return x+y+z
}
return a
}
8. 返回默认值
// 基础
func test()(int,string){
a :=0
b :="ok"
return 0,"ok"
}
// 返回默认值
func test()(a int,b string){ // 再这里指定了返回的默认值
// a和b不需要定义直接使用
a=0
b="ok"
// return的时候不需要指定了
return
}
// 没有返回值 return直接报错
func test(){
return
}
包
简介
包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从其它包中导入内容。
你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
一个 Go 程序是通过 import 关键字将一组包链接在一起。
https://blog.csdn.net/cscrazybing/article/details/78982064
- 同一个文件夹下只能有一个包,也就是package后面的名字要一致(默认就和文件夹的名字一样)
- 同一个包下不能有两个相同的函数名
- 使用包,需要导入(goland有自动导入功能)
- 导包的时候是从
gopath的src
开始导入的 - 以大写字母开头表示导出(外部包可以使用);小写字母开头,外部包不能使用,只能在包内部使用(直接使用即可)
package main
import "s12_day02/mypacakge" //导包的时候,是从gopath的src路径下开始导
import "fmt"
//包
//同一个文件夹下只能有一个包,也就是package 后面的名字都要一致
//默认就跟文件夹名字一样即可
//同一个包下有两个名字相同的函数是不行的
//使用包,需要导入
func main() {
mypackage.MyPackageTest()
//以大写字母开头表示导出(外部包可以使用),小写字母开头,外部包不能使用,只能再包内部适应
mypackage.test()
fmt.Println("xxx")
}
总结
- 1 新建一个文件夹(包),包下新建任意多个go文件,但是包名都必须一致(建议就用文件夹名)
- 2 在包内定义的函数,大写字母开头,表示外部包可以使用,小写字母开头,表示只能再内部使用,直接使用即可
- 3 在其他包中使用,要先导入(goland有自动提示)
-import "s12_day02/mypacakge"
-包名.函数() - 4 公有和私有 就是大小写区分的
- 5 所有的包必须在gopath的src路径下,否则找不到
// 类似于python中的包 包名叫 lqz 文件夹下有个__init__.py
__init__.py 写 文件夹下py文件
import lqz
lqz.能点出来的都在__init__.py中注册过
//go 中 包名.函数名,只要是大写开头的,都能点出来
导包
如果需要多个包,它们可以被分别导入:
import "fmt"
import "os"
或:
import "fmt"; import "os"
但是还有更短且更优雅的方法(被称为因式分解关键字,该方法同样适用于 const、var 和 type 的声明或定义):
import (
"fmt"
"os"
)
它甚至还可以更短的形式,但使用 gofmt 后将会被强制换行:
import ("fmt"; "os")
当你导入多个包时,导入的顺序会按照字母排序。
循环判断语句
if判断
语法
func main(){
if 条件 {
// 符合上面条件的
}else if 条件{
// 符合上面的条件的
}else{
// 不符合条件的
}
}
// 条件和大括号之间不能回车换行
使用
func main(){
var a =10
if a<9{
fmt.Println("小于9")
}else if a==10{
fmt.Println("10")
}else{
fmt.Println("都不符合")
}
// 也可以这样定义,但是a的作用域就不同了
func main(){
if a:=10;a<9{
fmt.Println("小于9")
}else if a==10{
fmt.Println("10")
}else{
fmt.Println("都不符合")
}
for循环
go中没有while循环,只有for循环(for可以替换while循环)
- 语法
func main(){
for关键字 初始化;条件;自增自减{
// 循环体的内容
}
}
- 代码
func main(){
// 基础循环体代码
for i :=0;i<10;i++{
fmt.Println(i)
}
// 省略第一部分
i:=0
for ;i<10;i++{
fmt.Println(i)
}
// 省略第三部分
i:=0
for ;i<10;{
fmt.Println(i)
i++
}
// 变形的while循环
i:=0
for i<10{
fmt.Println(i)
i++
}
// 省略第二部分(条件没了,死循环)
i:=0
for ;;{
fmt.Println(i)
i++
}
// 全省略的简略写法
for {
fmt.Println("xxx")
}
}
break continue
break 结束循环
continue 跳过本次循环
作业
1 编写代码打印9*9乘法表
func test(){
for i:=1;i<10 ;i++ {
for j:=1;j<=i;j++ {
fmt.Print(j,"*",i," ")
}
fmt.Println()
}
}
2 用闭包函数实现装饰器的功能
3 上课讲的5部分,代码都敲一遍
4 简历,继续写 with 上下文管理器的实现原理 django:mtv,orm 认证,ajax,上传文件 ,jwt,跨域,csrf,xss