闭包
package main
import "fmt"
func main() {
//这时候的f是方法
f := bibao()
//这时候的a才拿到的变量
a := f()
b := f()
//2
fmt.Println(a)
//3
fmt.Println(b)
}
// 闭包就是一个返回函数 来吧局部变量能够访问
func bibao() func() int {
i := 1
return func() int {
i += 1
return i
}
}
结构体
package main
import "fmt"
func main() {
//声明结构体类型
var a A
a.Name = "张三"
a.age = 66
//{张三 66}
fmt.Println(a)
}
// 将一个或者多个变量组合到一起 形成的类型 就是结构体struct 结构体也是值类型
type A struct {
Name string
age int
}
结构体指针
package main
import "fmt"
// 结构体
type A struct {
Name string
Age int
}
func main() {
//创建结构体指针
a := new(A)
a.Name = "张三"
a.Age = 17
b := &A{"张三", 17}
//&{张三 17}
fmt.Println(a)
//&{张三 17}
fmt.Println(b)
//打印地址值 0xc000060028 0xc000060030
fmt.Printf("%p %p \n", &a, &b)
//flase 因为他们比较的是地址值
fmt.Println(a == b)
//这样才是比较的结构体里面的值 才是true
fmt.Println(*a == *b)
}
方法
package main
import "fmt"
// 结构体
type A struct {
Name string
Age int
}
// 定义方法 方法必须是结构体 a是变量 aaa是函数名称
func (a A) aaa() {
fmt.Println(a.Name, "---------------", a.Age)
}
func main() {
a := A{"张三", 11}
//调用结构体的方法
a.aaa()
}
封装
package user
type User struct {
name string
age int
}
// 获取名称的方法
func (u *User) GetName() string {
return u.name
}
// 插入名称的方法
func (u *User) SetName(name string) {
u.name = name
}
package main
import (
"fmt"
"godemo/src/user"
)
// 封装就是把方法暴露给外面 方法首字母使用大写来控制权限
func main() {
a := new(user.User)
a.SetName("张三")
fmt.Println(a.GetName())
}
继承
package main
import "fmt"
type A struct {
name string
}
type B struct {
//只写A 就是继承了A的字段
A
}
func main() {
//创建B对象 并赋值
b := B{A{"张三"}}
//在这里可以直接.name 就是调用A的name
fmt.Println(b.name)
}
接口
package main
import "fmt"
// 接口就是只写方法 不写实现
type Jikeou interface {
aa(age int)
}
// 定义结构体
type A struct {
name string
}
// 结构体 继承 接口
func (a *A) aa(age int) {
fmt.Println(a.name)
fmt.Println(age)
}
func main() {
//创建对象
a := A{"张三"}
//张三 18
//调用方法
a.aa(18)
}
多态
package main
import "fmt"
type JieKou interface {
//定义方法
aa()
}
// 定义空的结构
type A struct {
}
type B struct {
}
// 多态就是方法名相同 结构不同
func (a *A) aa() {
fmt.Println("我是a")
}
func (b *B) aa() {
fmt.Println("我是b")
}
// 统一入口
func all(j JieKou) {
//调用接口的aa方法
j.aa()
}
func main() {
//带*的结构 必须在这里使用& 来创建对象 否则会编译不通过
a := &A{}
//我是a
all(a)
//传那个结构 就调用那个结构的方法 这就是多态
b := &B{}
//我是b
all(b)
}
断言
package main
import "fmt"
func main() {
定义接口是一个int
var i interface{} = 456
//断言这个i是不是int 如果是返回456 如果不是则报错
res := i.(int)
fmt.Println(res)
}
错误
package main
import "fmt"
// 定义方法 声明错误类型error
func aa(age int) (a int, e error) {
if age == 0 {
//如果是0直接报错
e.Error()
}
fmt.Println("没有出错")
//返回值赋值
a = age
//返回a
return
}
func main() {
//b 返回值,e 错误信息 如果是nil 就没有错误
b, e := aa(0)
fmt.Println(b, e)
}
defer
package main
import "fmt"
func main() {
fmt.Println("aaa")
defer fmt.Println("defer就是等所有的代码执行完毕之后,在延迟打印")
defer func() {
fmt.Println("defer 也可以结合方法,如果存在多个defer,那么按照栈的结构,先进,后出,后打印")
}()
fmt.Println("ccccc")
//也可以结合return使用
fmt.Println(bbb())
}
func bbb() (x int) {
a := 0
defer func() {
x = a + 2
}()
//返回x x=2
return
}
panic
package main
import "fmt"
func main() {
fmt.Println("我先执行")
panic("在我这里就停止了,抛出异常")
fmt.Println("这里不会打印了,因为上面使用了panic抛出了异常")
}
recover
package main
import "fmt"
func main() {
defer func() {
//接收panic的报错信息 让程序不会报错
recover()
}()
fmt.Println("aaa")
panic("报错了")
fmt.Println("bbbbbbb")
}
获取电脑信息
package main
import (
"fmt"
"os/user"
)
func main() {
//获取电脑信息
u, error := user.Current()
if error != nil {
fmt.Println("报错了", error)
}
fmt.Println("uid:", u.Uid)
fmt.Println("组id:", u.Gid)
fmt.Println("用户路径:", u.HomeDir)
fmt.Println("电脑名称:", u.Username)
}