2312 字
12 分钟
01、复习结构体

01、复习结构体#

// 复习结构体
type tmp struct {
x int
y int
}
type person struct {
name string
age int
}
func sum(x int, y int) (ret int) {
ret = x + y
return ret
}
// 构造(结构体变量的)函数,返回值是对应的结构体类型
func newPerson(n string, i int) (p person) {
p = person{
name: n,
age: i,
}
return p
}
// 方法
// 接收者使用对应类型的首字母小写
// 指定了接收者之后,只有接收者这个类型的变量才能调用这个方法
func (p *person) dream(str string) {
fmt.Printf("%s的梦想是%s.\n", p.name, str)
}
// func (p person) guonian() {
// p.age++ // 此处的p是p1的副本,改的是副本
// }
// 指针接收者
// 1. 需要修改结构体变量的值时要使用指针接收者
// 2. 结构体本身比较大,拷贝的内存开销比较大时也要使用指针接收者
// 3. 保持一致性:如果有一个方法使用了指针接收者,其他的方法为了统一也要使用指针接收者
func (p *person) guonian() {
p.age++ // 此处的p是p1的副本,改的是副本
}
func main() {
var b = tmp{
10,
20,
}
fmt.Println(b)
var a = struct {
x int
y int
}{10, 20}
fmt.Println(a)
var x int
y := int8(10)
fmt.Println(x, y)
var p1 person // 结构体实例化
p1.name = "周林"
p1.age = 9000
p2 := person{"保德路", 18} // 结构体实例化
p3 := person{"马笑", 20}
// 调用构造函数生成person类型变量
p4 := newPerson("nazha", 18)
fmt.Println(p1, p2, p3, p4)
p1.dream("做个咸鱼")
p2.dream("学好Go语言")
fmt.Println(p1.age)
p1.guonian()
fmt.Println(p1.age)
// 结构体嵌套
type addr struct {
province string
city string
}
type student struct {
name string
addr // 匿名嵌套别的结构体,就使用类型名做名称
}
type point struct {
X int `json:"zhoulin"`
Y int `json:"baodelu"`
}
po1 := point{100, 200}
// 序列化
b1, err := json.Marshal(po1)
// 如果出错了
if err != nil {
fmt.Printf("marshal failed, err:%v\n", err)
}
fmt.Println(string(b1))
// 反序列化:由字符串 --> Go中的结构体变量
str1 := `{"zhoulin":10010,"baodelu":10086}`
var po2 point // 造一个结构体变量,准备接收反序列化的值
err = json.Unmarshal([]byte(str1), &po2)
if err != nil {
fmt.Printf("unmarshal failed,err:%v\n", err)
}
fmt.Println(po2)
// map
m1 := map[int64]string{
10081: "哈哈哈",
10010: "嘿嘿嘿",
10000: "呵呵呵",
}
name1 := m1[20000]
fmt.Println(name1) // 取不到就返回value类型的零值
name2, ok := m1[2000] // ok=true表示有这个key,ok=false表示没有这key
fmt.Println(name2, ok)
// for k, v := range m1 {
// fmt.Println(k, v)
// }
// for k := range m1 {
// fmt.Println(k)
// }
}

02、interface-1#

// 引出接口的实例
// 定义一个能叫的类型
type speaker interface {
speak() // 只要实现了speak方法的变量都是speaker类型, 方法签名
}
type cat struct{}
type dog struct{}
type person struct{}
func (c cat) speak() {
fmt.Println("喵喵喵~")
}
func (d dog) speak() {
fmt.Println("旺旺旺~")
}
func (p person) speak() {
fmt.Println("啊啊啊~")
}
func da(x speaker) {
// 接收一个参数,传进来什么,我就打什么
x.speak() // 挨打了就要叫
}
func main() {
var c1 cat
var d1 dog
var p1 person
da(c1)
da(d1)
da(p1)
var ss speaker // 定义一个接口类型:speaker 的变量:ss
ss = c1
ss = d1
ss = p1
fmt.Println(ss)
}

03、接口示例2#

// 接口示例2
// 不管是什么牌子的车,都能跑
// 定义一个car接口类型
// 不管是什么结构体 只要有run方法都能是car类型
type car interface {
run()
}
type falali struct {
brand string
}
func (f falali) run() {
fmt.Printf("%s速度70迈~\n", f.brand)
}
type baoshijie struct {
brand string
}
func (b baoshijie) run() {
fmt.Printf("%s速度700迈~\n", b.brand)
}
// drive函数接收一个car类型的变量
func drive(c car) {
c.run()
}
func main() {
var f1 = falali{
brand: "法拉利",
}
var b1 = baoshijie{
brand: "保时捷",
}
drive(f1)
drive(b1)
}

04、接口的实现#

// 接口的实现
type animal interface {
move()
eat(string)
}
type cat struct {
name string
feet int8
}
func (c cat) move() {
fmt.Println("走猫步...")
}
func (c cat) eat(food string) {
fmt.Printf("猫吃%s...\n", food)
}
type chicken struct {
feet int8
}
func (c chicken) move() {
fmt.Println("鸡动!")
}
func (c chicken) eat(food string) {
fmt.Printf("吃%s...\n", food)
}
func main() {
var a1 animal // 定义一个接口类型的变量
fmt.Printf("%T\n", a1)
bc := cat{ // 定义一个cat类型的变量bc
name: "淘气",
feet: 4,
}
a1 = bc
a1.eat("小黄鱼")
fmt.Printf("%T\n", a1)
fmt.Println(a1)
kfc := chicken{
feet: 2,
}
a1 = kfc
fmt.Printf("%T\n", a1)
}

05、#

// 接口的实现
type animal interface {
move()
eat(string)
}
type cat struct {
name string
feet int8
}
func (c cat) move() {
fmt.Println("走猫步...")
}
func (c cat) eat(food string) {
fmt.Printf("猫吃%s...\n", food)
}
type chicken struct {
feet int8
}
func (c chicken) move() {
fmt.Println("鸡动!")
}
func (c chicken) eat(food string) {
fmt.Printf("吃%s...\n", food)
}
func main() {
var a1 animal // 定义一个接口类型的变量
fmt.Printf("%T\n", a1)
bc := cat{ // 定义一个cat类型的变量bc
name: "淘气",
feet: 4,
}
a1 = bc
a1.eat("小黄鱼")
fmt.Printf("%T\n", a1)
fmt.Println(a1)
kfc := chicken{
feet: 2,
}
a1 = kfc
fmt.Printf("%T\n", a1)
}

06、#

// 使用值接收者和指针接收者的区别?
type animal interface {
move()
eat(string)
}
type cat struct {
name string
feet int8
}
// // 使用值接收者实现了接口的所有方法
// func (c cat) move() {
// fmt.Println("走猫步...")
// }
// func (c cat) eat(food string) {
// fmt.Printf("猫吃%s...\n", food)
// }
// 使用指针接收者实现了接口的所有方法
func (c *cat) move() {
fmt.Println("走猫步...")
}
func (c *cat) eat(food string) {
fmt.Printf("猫吃%s...\n", food)
}
func main() {
var a1 animal
c1 := cat{"tom", 4} // cat
c2 := &cat{"假老练", 4} // *cat
a1 = &c1 // 实现animal这个接口的是cat的指针类型,
fmt.Println(a1)
a1 = c2
fmt.Println(a1)
}

07、#

// 同一个结构体可以实现多个接口
// 接口还可以嵌套
type animal interface {
mover
eater
}
type mover interface {
move()
}
type eater interface {
eat(string)
}
type cat struct {
name string
feet int8
}
// cat实现了mover接口
func (c *cat) move() {
fmt.Println("走猫步...")
}
// cat实现了eater接口
func (c *cat) eat(food string) {
fmt.Printf("猫吃%s...\n", food)
}
func main() {
}

08、#

// 空接口
// interface: 关键字
// interface{} :空接口类型
// 空接口作为函数参数
func show(a interface{}) {
fmt.Printf("type:%T value:%v\n", a, a)
}
func main() {
var m1 map[string]interface{}
m1 = make(map[string]interface{}, 16)
m1["name"] = "周林"
m1["age"] = 9000
m1["merried"] = true
m1["hobby"] = [...]string{"唱", "跳", "rap"}
fmt.Println(m1)
show(false)
show(nil)
show(m1)
}

09、#

type ff func()
// 类型断言1
func assign(a interface{}) {
fmt.Printf("%T\n", a)
str, ok := a.(string)
if !ok {
fmt.Println("猜错了")
} else {
fmt.Println("传进来的是一个字符串:", str)
}
}
// 类型断言2
func assign2(a interface{}) {
fmt.Printf("%T\n", a)
switch t := a.(type) {
case string:
fmt.Println("是一个字符串:", t)
case int:
fmt.Println("是一个int:", t)
case int64:
fmt.Println("是一个int64:", t)
case bool:
fmt.Println("是一个bool:", t)
case []int:
fmt.Println("是一个slice:", t)
case map[string]int:
fmt.Println("是一个map[string]int:", t)
case func():
fmt.Println("是一个函数类型:", t)
}
}
func f() {
}
func main() {
// assign(100)
assign2(true)
assign2("哈哈哈")
assign2(int64(200))
assign2([]int{1, 2, 3})
assign2(map[string]int{"a": 1})
assign2(f)
}

10、#

func init() {
fmt.Println("import 我时自动执行...")
}
// 包中的标识符(变量名\函数名\结构体\接口等)如果首字母是小写的,表示私有(只能在当前这个包中使用)
// 首字母大写的标识符可以被外部的包调用
func Add(x, y int) int {
return x + y
}

11、调用10init的函数#

var x = 100
const pi = 3.14
func init() {
fmt.Println("自动执行!")
fmt.Println(x, pi)
}
func main() {
ret := zhoulin.Add(10, 20)
fmt.Println(ret)
}

12、#

// 打开文件
func readFromFile1() {
fileObj, err := os.Open("./main.go")
if err != nil {
fmt.Printf("open file failed, err:%v", err)
return
}
// 记得关闭文件
defer fileObj.Close()
// 读文件
// var tmp = make([]byte, 128) // 指定读的长度
var tmp [128]byte
for {
n, err := fileObj.Read(tmp[:])
if err == io.EOF {
fmt.Println("读完了")
return
}
if err != nil {
fmt.Printf("read from file failed, err:%v", err)
return
}
fmt.Printf("读了%d个字节\n", n)
fmt.Println(string(tmp[:n]))
if n < 128 {
return
}
}
}
// 利用bufio这个包读取文件
func readFromFilebyBufio() {
fileObj, err := os.Open("./main.go")
if err != nil {
fmt.Printf("open file failed, err:%v", err)
return
}
// 记得关闭文件
defer fileObj.Close()
// 创建一个用来从文件中读内容的对象
reader := bufio.NewReader(fileObj)
for {
line, err := reader.ReadString('\n')
if err == io.EOF {
return
}
if err != nil {
fmt.Printf("read line failed, err:%v", err)
return
}
fmt.Print(line)
}
}
func readFromFileByIoutil() {
ret, err := ioutil.ReadFile("./main.go")
if err != nil {
fmt.Printf("read file failed, err:%v\n", err)
return
}
fmt.Println(string(ret))
}
func main() {
// readFromFile1()
// readFromFilebyBufio()
readFromFileByIoutil()
}

13、#

// 打开文件写内容
// 0100 0000
func writeDemo1() {
fileObj, err := os.OpenFile("./xx.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
fmt.Printf("open file failed, err:%v", err)
return
}
// write
fileObj.Write([]byte("zhoulin mengbi le!\n"))
// writeString
fileObj.WriteString("周林解释不了!")
fileObj.Close()
}
func writeDemo2() {
fileObj, err := os.OpenFile("./xx.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
fmt.Printf("open file failed, err:%v", err)
return
}
defer fileObj.Close()
// 创建一个写的对象
wr := bufio.NewWriter(fileObj)
wr.WriteString("hello沙河\n") // 写到缓存中
wr.Flush() // 将缓存中的内容写入文件
}
func writeDemo3() {
str := "hello 沙河"
err := ioutil.WriteFile("./xx.txt", []byte(str), 0666)
if err != nil {
fmt.Println("write file failed, err:", err)
return
}
}
func writeDemo3
func main() {
// writeDemo1()
// writeDemo2()
writeDemo3()
}

14、#

// 二进制实用途
const (
eat int = 4
sleep int = 2
da int = 1
)
// 111
// 左边的1表示吃饭 100
// 中间的1表示睡觉 010
// 右边的1表示打豆豆 001
func f(arg int) {
fmt.Printf("%b\n", arg)
}
func main() {
f(eat | da) // 101
f(eat | sleep | da) // 111
}

15、#

// 获取用户输入时如果有空格
func useScan() {
var s string
fmt.Print("请输入内容:")
fmt.Scanln(&s)
fmt.Printf("你输入的内容是:%s\n", s)
}
func useBufio() {
var s string
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入内容:")
s, _ = reader.ReadString('\n')
fmt.Printf("你输入的内容是:%s\n", s)
}
func main() {
// useScan()
useBufio()
// logger.Trace()
// logger.Debug()
// logger.Warning()
// logger.Info()
// logger.Error("日志的内容")
// 写日志
fmt.Fprintln(os.Stdout, "这是一条日志记录!")
fileObj, err := os.OpenFile("./xxx.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("日志写入失败")
return
}
fmt.Fprintln(fileObj, "这是一条日志记录!")
}

16、#

01、复习结构体
https://blog.zhequtao.com/posts/golang/go-new/base/base05/
作者
阿俊
发布于
2020-03-30
许可协议
CC BY-NC-SA 4.0

相关阅读