#
为什么几乎就 python 中的注释是 # ?
代码几乎都要写在 main 函数里执行(本文写的都是伪代码) 本文仅是跟着视频学习做的笔记,并未花时间去校对,如有错误,别太当真 重复定义是错误的,我的代码里有很多重复定义,只是为了写出来,你 copy 过去用的时候记得把重复定义删掉
内层函数:定义在函数内部的函数
闭包函数:定义在函数内部,对外部作用域有引用(闭包函数本质也是内层函数)
在 go 语言中没有像 python 中的装饰器语法糖,但可以自己实现类似功能
// 内层函数
func test(a int) (func()) {
// var c int = 100
b := func() {
fmt.println("我是内层函数(定义在了函数内部,但没有引用外部作用域)")
}
}
// 闭包函数
func test(a int) (func()) {
// var c int = 100
b := func() {
fmt.println(a) // 是闭包函数,本身也是内层函数
}
}
// 模仿 python 装饰器的写法
// 定义一个函数,传入函数,返回函数
func test(a func()) func() {
b:= func() {
fmt.Println("我先执行")
a()
fmt.Println("函数执行完了")
}
return b
}
func test2() {
fmt.Println("xxxx")
}
func main() {
a := test2
a = test(a)
a()
//我先执行
//xxxx
//函数执行完了
}
给类型取别名 type MyFunc func(a, b int) func()
取了别名之后,用了别名的变量和原来的类型不是同一个类型了
// 给类型命别名
func main() {
type MyInt int
var a MyInt = 10
var b int = 90
// a = b // 会报错,类型不匹配
a = MyInt(b) // 强转成一个类型
fmt.Println(a)
// 90
}
// 用在函数上面来简化写法
type MyFunc func(a int,b int) func()
type MyInt int
func test() (MyFunc) {
c:= func(a int,b int) func(){
return func() {
}
}
return c
}
func main() {
var a MyInt=10
var b int =90
a=MyInt(b)
fmt.Println(a)
// 90
}
if else if else
跟 js 的写法差不多
if 条件 {
三个之间不能有换行(所有语言每一句结束都应该有一个 ;
,很多语言都做了封装),如果加了换行,go 会自动在条件后面加上 ;
,那么语义就错了package main
import "fmt"
func main() {
if a := 90; a > 90 {
fmt.Println("a>90")
} else if a > 70 {
fmt.Println("a>70")
} else {
fmt.Println(a)
}
}
//a>70
go 的包管理一直被人所诟病(go 还是一门比较年轻的语言,需要时间来成长)
1)通常情况下,包名就是文件夹,在同一个文件夹下的 go 文件,文件里的包名必须一致
2)同一个包下定义的东西(变量、常量、函数)不能重名
3)在包内定义的函数如果是小写字母开头,表示只能在包内使用(外部无法引用)
4)go 里导包只能导到包名那一层,不能说导里面的方法属性这些(import 包名
)
go 是一个开源的社区语言,所以并没有 python 那样一个专门的 pipy 来下载模块镜像,都是去各个地方下载
go get github.com/astaxie/beego(地址)
go 的优点之一
可以了解一下 Supervisord(beego 官网文档里有)
// 不能重复定义,这里面的代码只是案例
package main
import "fmt"
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; { // 或
for i < 10 { // 等同于 python 里的 while 循环 --> while True ==》 for True
fmt.Println(i)
i++
}
// 死循环
// for ;; { // 或
for {
fmt.Println("xxx")
}
// 注意下作用域范围(循环里定义的变量只能在循环里用)
// --------中断或跳过本次循环--------
// 用的是 break 和 continue,和其他语言的用法是一样的
for i := 0; i < 10; i++ {
if i == 5 {
break
}
fmt.Println(i)
}
for i := 0; i < 10; i++ {
if i == 5 {
continue
}
fmt.Println(i)
}
}
package main
import "fmt"
func main() {
//a := 10
//switch a {
//case 1:
// fmt.Println("1")
//case 2, 3, 4:
// fmt.Println("2-4")
// fallthrough // 只要读到这个,会无条件执行下面一个 case 内容
//case 5:
// fmt.Println("5,a 是 2-4时顺带执行我")
//default: // 都不匹配,会执行这个
// fmt.Println("都不是")
//}
////都不是
// 无表达式的 switch
a := 10
switch {
case a > 10:
fmt.Println("a大于10")
case a < 10:
fmt.Println("a小于10")
default:
fmt.Println("a等于10")
}
// a等于10
}
// 不能重复定义,这里面的代码只是案例
package main
import "fmt"
func main() {
var a [5] int // 定义了一个长度为5的 int 类型数组
fmt.Println(a)
// [0 0 0 0 0]
a[1] = 100 // 索引是从 0 开始的
fmt.Println(a)
// [0 100 0 0 0]
// 定义并赋初值
var a [6]int = [6]int{1,2,3,4,5,6}
var a = [6]int{1,2,3} // int 类型省略的几个自动用 0 填充
a := [100]int{98:99} // 把第99个(索引是98)设置成99
a := [100]int{1,2,3,98:99,87:88}
// 不支持负数索引
}
package main
import "fmt"
func main() {
a := [4]int{1,2,3}
test7(a)
fmt.Println(a)
}
func test7(b [4]int) {
b[0]=100
fmt.Println(b)
}
// [100 2 3 0]
// [1 2 3 0]
go 1.5版本之前都是用C写的,但后面就开始用go语言写了
// a 和 b 不是同一个类型
var a [4]int
var b [5]int
// 不同类型无法直接赋值,也无法直接做大小比较
package main
import "fmt"
func main() {
var a [4]int = [4]int{1,2,}
for i:=0;i<len(a);i++{ // len 可以获取数组长度
fmt.Println(a[i])
}
//1
//2
//0
//0
// 通过 range 迭代(range是一个关键字)
for i, v := range a { // for 索引,值 range 可迭代对象
fmt.Println("-----", i) // 索引
fmt.Println(v) // 值
}
//----- 0
//1
//----- 1
//2
//----- 2
//0
//----- 3
//0
for i := range a { // 一个值就是索引
fmt.Println("-----", i)
}
//----- 0
//----- 1
//----- 2
//----- 3
}
package main
import "fmt"
func main() {
var a [7][2]int
fmt.Println(a)
// [[0 0] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]
a[0][1]=100
fmt.Println(a)
// [[0 100] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]]
}
&& || !
package main
import "fmt"
func main() {
a := 13
if !(a < 1 && a > 0 || a == 6) {
fmt.Println("success.")
// success.
}
}