go入门篇

代码示例:

import _ "github.com/go-sql-driver/mysql"

// _操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的 init 函数。

-----------------------------------------------------------------------------

package main //声明文件所在的包,每个go文件必须有归属的包

import "fmt" //引入程序中需要的包,为了使用包下的函数,比如:Println

func main() { //main 主函数,程序入口

    fmt.Println("Hello Golang!") //在控制台打印输出一句话,双引号中的内容会原样输出

}

参数解析两种:

name := flag.String("name","world","specify the name")flag  //解析参数如go run main.go --name jason, 这样就解析了--name

flag.Parse()

fmt.Println("os args is:", os.Args) //打印程序名和参数

自定义报错:

fmt.Errorf("aaa is not allowed") //抛出一个报错

编译执行:

go build test.go

./test.exe

go run test.go  #编译和运行

定义变量和使用:

package main

import "fmt"

//全局变量:定义在函数外的变量

// var n7 = 100

// var n8 = 9.7

//或

var (

    n7 = 100

    n8 = 9.7

)

func main() {

    //定义在{}中的变量叫:局部变量

    // 第一种: 变量的使用方式

    var num int = 18

    fmt.Println(num)

    //第二种: 指定变量类型,但是不赋值,使用默认的变量值

    var num2 int

    fmt.Println(num2)

    //第三种: 如果没有协变量的类型,那么根据=后面的值进行判定变量的类型(自动类型推断)

    var num3 = "tom"

    fmt.Println(num3)

    //第四种:省略var, 注意:=不能写为=

    sex := "男"

    fmt.Println(sex)

    fmt.Println("-------------------------------")

    //声明多个变量,短变量声明:

    n1, n2, n3 := 1, 2, 3

    fmt.Println(n1, n2, n3)

    fmt.Println(n7)

}

函数外的每个语句都必须以关键字开始(所以短变量不能在函数体外声明,函数体外部声明需要用var)

数据类型:

基本数据类型:

  - 数值型

    - 整数类型(int)  #int8占用存储空间1字节(1字节=8位),默认为0

    - 浮点类型(float) #默认为0

  - 字符型(没有单独的字符型,使用byte来保存单个字母字符)

  - 布尔型(bool)      #默认是false

  - 字符串(string)    #默认为空

基本数据类型间的转换(显示转换):

基本类型转string类型

方式1:fmt.Sprintf("%参数",表达式)    ---》 重点练习这个,推荐方式

package main

import "fmt"

func main(){

        var n1 int = 19

        var n2 float32 = 4.78

        var n3 bool = false

        var n4 byte = 'a'

        var s1 string = fmt.Sprintf("%d",n1)

        fmt.Printf("s1对应的类型是:%T ,s1 = %q \n",s1, s1)

        var s2 string = fmt.Sprintf("%f",n2)

        fmt.Printf("s2对应的类型是:%T ,s2 = %q \n",s2, s2)

        var s3 string = fmt.Sprintf("%t",n3)

        fmt.Printf("s3对应的类型是:%T ,s3 = %q \n",s3, s3)

        var s4 string = fmt.Sprintf("%c",n4)

        fmt.Printf("s4对应的类型是:%T ,s4 = %q \n",s4, s4)

        //变量定义后不能再定义一个同样的变量,只能修改

        i := 0

        i = 1    //这里是修改,所以不能加冒号再次定义

        fmt.Println(i)

}

方式2:使用strconv包的函数 

复杂数据类型:

  - 指针(创造出来的目的是节省内存的)

      打印空间地址:

          var age int 18

          fmt.Println(&age)    #获取age的地址

          var ptr *int = &age  #定义一个指针

          fmt.Println(&ptr)    #获取ptr指针的地址

          fmt.Println(*ptr)    #获取ptr这个指针指向的数据

          或者:

          v4 := new(int) //定义指针,new是用于创建内存并进行内部数据的初始化,并返回一个指针类型。并且给一个默认值为0, 先开一个内存空间给一个内存地址,然后指向值为0

          var v3 *int    //和上面同样,如果没给值的话,指向的值为nil值

          nil //nil指go语言中的空值,比如var v100 *int和var v101 *int6 默认都指向nil

  数组

  结构体

  管道

  函数

  切片

  接口

  map

命名规范

变量名、函数名、常量名 : 采用驼峰法

如果变量名、函数名、常量名首字母大写,则可以被其他的包访问

如果首字母小写,则只能在本包中使用

运算符

算数运算:  +, -, *, /, %

赋值运算符:  =, +=, -=, *=, /=, %=

逻辑运算符: ==, !=, >, <, >=, <=

位运算符:  &, |, ^

其他运算符: &, *

获取用户终端输入

scanln

scanf

if

在golang里,if后面可以并列的加入变量的定义

if count := 20;count < 30 {

                fmt.Println("对不起,口罩存量不足")

        }

多分支

    方式一:

    var count int = 111

    if count < 30 {

        fmt.Println("对不起,口罩存量不足")

    } else if 30 < count && count < 50 {

        fmt.Println("口罩存量充足")

    } else {

        fmt.Println("口罩存量很多")

    }


    方式二:

    if count >= 50 {

        fmt.Println("口罩存量很多")                           

    } else if count >=30 {    // count <= 50 && count >=30,因为包含了else

        fmt.Println("口罩存量充足")   

    } else {

        fmt.Println("对不起,口罩存量不足")   

    }  //建议保证else存在,只有有了else才会真正的起到多选一的效果

Switch分支

一般来实现多分支

func main() {

    var score int = 87

    switch score / 10 {    //switch后面跟表达式,表达式的结果依次跟case进行比较,放变量、常量、函数都可以

        case 10:        //case后面可以写多个值,使用逗号分隔,如case 10,11,12:

            fmt.Println("您的等级为A级")

        case 9:

            fmt.Println("您的等级为A级")

        case 8:

            fmt.Println("您的等级为B级")

        case 7:

            fmt.Println("您的等级为C级")

        case 10:

            fmt.Println("您的等级为D级")

        case 6:

            fmt.Println("您的等级为E级")

        case 5:

            fmt.Println("您的等级为E级")

        case 4:

            fmt.Println("您的等级为E级")

        case 3:

            fmt.Println("您的等级为E级")

        default:    //default分支可以放到任意位置上

            fmt.Println("您的等级有误")

    }

}

for循环

package main

import "fmt"

func main() {

    var sum int = 0

    for i := 1; i <= 5; i++ {

        fmt.Println(i, sum)

        sum += i

    }

}

灵活写法:

    var i int = 1

    for i <= 5 {

        fmt.Println("nihao")

        i++

    }


死循环:

    for {

        fmt.Println("nihao")

    }

for range

package main

import "fmt"

func main() {

    var str string = "hello golang你好"

    for i, value := range str {

        fmt.Printf("索引为: %d, 具体的值为: %c\n", i, value)

    }

}

break

package main

import "fmt"

func main() {

    var sum int = 0

    for i := 1; i <= 100; i++ {

        sum += i

        fmt.Println(sum)

        if sum >= 300 {

            break    //停止并跳出当前循环

        }

    }

}

可以给每个循环加label,使用break label可以结束指定标签的循环:

package main

import "fmt"

func main() {

    //双重循环:

label2:

    for i := 1; i <= 5; i++ {

        for j := 2; j <= 4; j++ {

            fmt.Printf("i: %v, j: %v \n", i, j)

            if i == 2 && j == 2 {

                break label2 //结束指定标签对应的循环

            }

        }

    }

    fmt.Println("-----ok")

}

continue

package main

import "fmt"

func main() {

    for i := 1; i <= 100; i++ {

        if i%6 != 0 {

            continue //结束本次循环,继续下一次循环。

        }

        fmt.Println(i)

    }

}

continue也可以跟label:

package main

import "fmt"

func main() {

    //双重循环:

label:

    for i := 1; i <= 5; i++ {

        for j := 2; j <= 4; j++ {

            if i == 2 && j == 2 {

                continue label

            }

            fmt.Printf("i: %v, j: %v \n", i, j)

        }

    }

    fmt.Println("-----ok")

}

return

结束当前的函数

函数

调用函数:

package main

import "fmt"

func cal(num1 int, num2 int) (int) {  //(int) 表示指定返回值的类型,如果没有return,可以不写。如果返回值只有一个,那(int)的括号可以不写。如果返回值多个,需要写上,如(int, int)

    return num1 + num2

}

func main() {

    sum := cal(20, 20)

    fmt.Println(sum)

}

函数可以返回两个值和多个值:

package main

import "fmt"

func cal(num1 int, num2 int) (int, int) {

    var sum int = 0

    sum += num1

    sum += num2

    var result int = num1 - num2

    return sum, result

}

func main() {

    sum, result := cal(20, 20) //或者只想接收sum,可以这样:sum, _ := cal(20, 20), _表示忽略

    fmt.Println(sum, result)

}

可变参数(使用...)

package main

import "fmt"

func test(args ...int) {   

    for i := 0; i < len(args); i++ {

        fmt.Println(args[i])

    }

}

func main() {

    test()

    test(3)

    test(1, 2, 3, 4, 5, 6, 7, 8)

}

改main函数里的变量值(用到指针,通过内存地址传递来改)

package main

import "fmt"

func test(num *int) {

    *num = 30

}

func main() {

    var num int = 10

    fmt.Println(&num)

    test(&num)

    fmt.Println(num)

}

将函数赋给变量

type起别名

对函数返回值命名

package main

import "fmt"

func test(num1 int, num2 int) (sum int, sub int) {

    sum = num1 + num2

    sub = num1 - num2

    return

}

func main() {

    ss, bb := test(10, 20)

    fmt.Println(ss, bb)

}

包的引入(引入的包里函数必须大写开头才能被引用)

main.go  //导入utils.go中的函数

utils.go  //专门定义一些工具函数,让其他文件来调用

db.go  //专门定义对数据库操作的函数

包名是从$GOPATH/src/后开始计算的,使用/进行路径分隔

多个包导入:

import(

        "fmt"

        "gocode/testproject01/unit5/demo09/crm/dbutils"

)

函数名,变量名首字母大写,函数,变量可以被其它包访问

init函数(优先执行,用于一些初始化操作,只运行一次)

package main

import "fmt"

func init() {

    fmt.Println("init函数被执行")

}

func main() {

    fmt.Println("main函数被执行")

}

匿名函数(只调用一次,使用一次)

package main

import "fmt"

func main() {

    result := func(num1 int, num2 int) int {

        return num1 + num2

    }(10, 20)

    fmt.Println(result)

}

闭包:

    - 也是一个匿名函数

    - 不能独立存在

    - 可以赋值给其他变量

      x := func(){}

    - 可以直接调用

      func(x,y int){println(x+y)}(1,2)

    - 可以作为函数返回值

      func Add() (func(b int) int)


defer func(){

    if r :=recover(); r != nil {

        println("recovered in FuncX")

    }

}

x := func(){}  //一个函数的声明

系统函数(需要导包)

1.打印字符串长度len():

package main

import "fmt"

func main() {

    str := "golang你好"

    fmt.Println(len(str))

}

2.字符串遍历:

package main

import "fmt"

func main() {

    str := "golang你好"

    fmt.Println(len(str))

    for i, value := range str {

        fmt.Printf("索引为: %d, 具体值: %c\n", i, value)

    }

}

或利用切片:

r := []rune(str)

for i := 0; i < len(r); i++ {

    fmt.Println(r[i])

}

3.字符串转整数

num1, _ := strconv.Atoi("666")

fmt.Printf("%T", num1)

4.整数转字符串

num1 := strconv.Itoa(666)

fmt.Println(num1)

5.查找字符串是否在指定的字符串中

count := strings.Contains("javaandgolang", "goo")

fmt.Println(count)

6.统计一个字符串有几个指定的子串

count := strings.Count("javaandgolang", "a")

fmt.Println(count)

7.不区分大小写的字符串比较

count := strings.EqualFold("go", "Go")

fmt.Println(count)

8.区分大小写的字符串比较

fmt.Println("hello" == "Hello")

9.返回字符串在字符串第一次出现的索引值,如果没有返回-1

fmt.Println(strings.Index("golangandjavaga", "ga0"))

10.字符串的替换

strings.Replace("goandjavagogo", "go", "golang", n)  //n可以指定你希望替换几个,如果n=-1表示全部替换,替换两个n就是2

str := strings.Replace("goandjavagogo", "go", "golang", 2)

fmt.Println(str)

11.按照指定的某个字符,为分割标识,将一个学符串拆分成字符串数组

strings.Split("go-python-java", "-")

str := strings.Split("go-python-java", "-")

fmt.Println(str)

12.将字符串的字母进行大小写的转换

str := strings.ToLower("Go")

str1 := strings.ToUpper("go")

fmt.Println(str, str1)

13.将字符串左右两边的空格去掉

str := strings.TrimSpace("    go and java    ")

fmt.Println(str)

14.将字符串左右两边指定的字符去掉

strings.Trim("~golang~ ", " ~")

15.将字符串右边指定的字符去掉

strings.TrimRight("~golang~", "~")

16.将字符串左边指定的字符去掉

strings.TrimLeft("~golang~", "~")

17.判断字符串是否以指定的字符串开头

strings.HasPrefix("http://java.sun.com/jsp/jstl/fmt", "http")

18.判断字符串是否以指定的字符串结束

strings.HasSuffix("demo.png", ".png")

日期函数:

1.获取当前时间

now := time.Now()

fmt.Println(now)

2.当想获取指定的字段

import (

    "fmt"

    "time"

)

func main() {

    now := time.Now()

    fmt.Printf("%v~~~~对应的类型为: %T\n", now, now)

    // fmt.Println(now)

    fmt.Printf("年: %v \n", now.Year())

    fmt.Printf("月: %v \n", int(now.Month()))

    fmt.Printf("日: %v \n", now.Day())

    fmt.Printf("时: %v \n", now.Hour())

    fmt.Printf("分: %v \n", now.Minute())

    fmt.Printf("秒: %v \n", now.Second())

}

3.日期的格式化,将日期以年月日时分秒按照格式输出为字符串,如果是printf只是将字符串输出,而sprintf可以赋值给变量

datestr := fmt.Sprintf("当前年月日: %d-%d-%d 时分秒: %d:%d:%d", now.Year(), int(now.Month()), now.Day(), now.Hour(), now.Minute(), now.Second())

fmt.Println(datestr)

4.按照指定格式(里面的时间和日期不能修改)

datestr2 := now.Format("2006/01/02 15:04:05")

fmt.Println(datestr2)

datestr3 := now.Format("2006/01/02 15:04")

fmt.Println(datestr3)

内置函数(不需要导包,直接使用):

close //管道关闭

len, cap  //返回数组、切片、Map的长度或容量

new, make  //内存分配

copy, append  //操作切片

panic, recover //错误处理

print, println  //打印

complex, real, imag  //操作复数

5.new函数,分配内存,主要用来分配值类型(int系列, float系列, bool, string、数组和结构体struct)

6.分配内存,主要用来分配引用类型(指针、slice切片、map、管道chan、interface 等)

回调函数(Callback,函数作为参数传入其他函数,并在其他函数内部调用执行)

错误处理

package main

import (

    "fmt"

)

func main() {

    test()

    fmt.Println("上面的除法操作成功。。。")

    fmt.Println("正常执行下面的逻辑。。。")

}

func test() {

    defer func() { //匿名函数,捕获错误,程序不会轻易的挂掉,提高程序的健壮

        err := recover()

        if err != nil {

            fmt.Println("错误已经捕获")

            fmt.Println("err是:", err)

        }

    }()

    num1 := 10

    num2 := 0

    result := num1 / num2

    fmt.Println(result)

}

自定义错误:需要调用errors包下的New函数:函数返回error类型

package main

import (

    "errors"

    "fmt"

)

func main() {

    err := test()

    if err != nil {

        fmt.Println("自定义错误:", err)

        panic(err) //加入panic后,程序终止

    }

    fmt.Println("上面的除法操作成功。。。")

    fmt.Println("正常执行下面的逻辑。。。")

}

func test() (err error) {

    num1 := 10

    num2 := 0

    if num2 == 0 {

        //抛出自定义错误

        return errors.New("除数不能为0~~")

    } else {

        result := num1 / num2

        fmt.Println(result)

        return nil

    }

}

数组

定义格式:var 数组名 [数组大小]数据类型

package main

import "fmt"

func main() {

    var scores [5]int

    scores[0] = 95

    scores[1] = 91

    scores[2] = 39

    scores[3] = 60

    scores[4] = 21

    sum := 0

    for i := 0; i < len(scores); i++ {

        sum += scores[i]

    }

    fmt.Println(sum)

}

遍历数组一般用for range:

    for stu, score := range scores {

        fmt.Printf("第%d个学生的成绩为: %d\n", stu+1, score)

    }

数组的初始化(必须定义长度):

package main

import "fmt"

func main(){

        //第一种:

        var arr1 [3]int = [3]int{3,6,9}

        fmt.Println(arr1)

        //第二种:

        var arr2 = [3]int{1,4,7}

        fmt.Println(arr2)

        //第三种:

        var arr3 = [...]int{4,5,6,7}

        fmt.Println(arr3)

        //第四种:

        var arr4 = [...]int{2:66,0:33,1:99,3:88}    //下标为2位置上的值是66

        fmt.Println(arr4)

二维数组初始化:

    var arr = [2][3]int{{1, 3, 4}, {2, 3, 5}}

    fmt.Println(arr)

切片(构建在数组之上,用数组的情况少,切片的时候多)

package main

import "fmt"

func main() {

    var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}

    slice := intarr[1:3]    //1-3,不包含3, 定义切片是:=, 定义数组是=

    fullSlice := intarr[:]  //不限下标,意思就是整个

    fmt.Println(slice)

}

添加:

mySlice := []int{}    //slice []不会定义长度

mySlice := myArrayp[1:3]

mySlice = append(mySlice, 1)

删除很麻烦,需要自定义一个删除函数:

func deleteItem(slice []int, index int) []int {

    return append(slice[:index], slice[index+1:]...)

}

比如删除索引2的切片:

package main

import (

    "fmt"

)

func main() {

    myArray := [5]int{1, 2, 3, 4, 5}

    mySlice := myArray[1:3]

    fmt.Printf("mySlice %+v\n", mySlice)

    fullSlice := myArray[:]

    fmt.Println(fullSlice)

    remove3rdItem := deleteItem(fullSlice, 2)

    fmt.Printf("remove3rdItem %+v\n", remove3rdItem)

}

func deleteItem(slice []int, index int) []int {

    return append(slice[:index], slice[index+1:]...)

}

构造切片: 可以使用New和Make

New:

make: 关注程序运行效率的话,需要定义好length(长度)和cap(容量),不然程序会自己去内存找

go语言在任何地方都是值传递,比如我要修改数组的元素,直接修改元素对原有的数组没影响,需要根据下标来修改

mySlice := []{10,20,30,40,50}

//这样相当于定义了一个value的临时变量来乘以2,对原有的元素不影响

for _,value := range mySlice {

    value *= 2

}

fmt.Printf("mySlice %+v\n", mySlice)    //%v只把值原样打印,%+v会把类型也打印出来,一般用来debug

//打印值:mySlice [10 20 30 40 50]

//Printf() 是把格式化字符串输出到标准到标准输出(一般是屏幕,可以重定向)

//Sprintf() 是把格式化字符串输出到指定的字符串中,可以用一个变量来接受,然后在打印

//这样才是影响原有的元素,通过下标的方式

for index,_ := range mySlice {    //_可以不要,因为是取下标了

    mySlice[index] *= 2

}

fmt.Printf("mySlice %+v\n", mySlice)

//打印值:mySlice [20 40 60 80 100]

map(键值对(key-value): 一堆匹配的信息),相当于字典,定义:make(map[type of key]type of value)

比如:学生学号 - 学生姓名

package main

import "fmt"

func main() {

    // var a map[int]string

    //myMap := make(map[string]string, 10)

    var a = make(map[int]string, 10)    //可以存10个键值对

    a[20095452] = "张山"

    a[20095387] = "李四"

    a[20097291] = "王五"

    fmt.Println(a)

}

使用前一定要make

key-value是无序的

定义方式:

package main

import "fmt"

func main(){

        //方式1:

        //定义map变量:

        var a map[int]string

        //只声明map内存是没有分配空间

        //必须通过make函数进行初始化,才会分配空间:

        a = make(map[int]string,10) //map可以存放10个键值对

        //将键值对存入map中:

        a[20095452] = "张三"

        a[20095387] = "李四"

        //输出集合

        fmt.Println(a)

        //方式2:

        b := make(map[int]string)

        b[20095452] = "张三"

        b[20095387] = "李四"

        fmt.Println(b)

        //方式3:

        c := map[int]string{

                20095452 : "张三",

                20098765 : "李四",

        }

        c[20095387] = "王五"

        fmt.Println(c)

}

增和改:

没有就添加,有就修改

删:

delete(b,20095387) //b[20095387]

查:

package main

import "fmt"

func main() {

    //定义map

    b := make(map[int]string)

    //增加:

    b[20095452] = "张三"

    b[20095387] = "李四"

    //修改:

    b[20095452] = "王五"

    //删除:

    // delete(b, 20095387)

    delete(b, 20089546)

    // fmt.Println(b)

    //查找:

    value, flag := b[20095387]    //flag为bool型,如果value存在,则为true,反之为false

    fmt.Println(value)

    fmt.Println(flag)

    if flag {    //习惯性语法,kubernetes经常用到

        Println(value)   

    }

}

获取长度:

fmt.Println(len(b))

遍历,只能for range:

    a := make(map[string]map[int]string)

    a["班级1"] = make(map[int]string, 3)

    a["班级1"][20096677] = "zhangshan"

    a["班级1"][20098833] = "lisi"

    a["班级1"][20097722] = "ffei"

    a["班级2"] = make(map[int]string, 3)

    a["班级2"][20089911] = "xiaoming"

    a["班级2"][20085533] = "xiaolong"

    a["班级2"][20087244] = "xiaobei"

    for k1, v1 := range a {

        fmt.Println(k1)

        for k2, v2 := range v1 {

            fmt.Printf("学生学号: %v, 学生姓名: %v\n", k2, v2)

        }

    }

面向对象(类-结构体struct)

结构体 -> 类

结构体支持标签

type MyType struct {

    Name string `json:"name"`

}

func main(){

    mt := MyType{Name: "test"}

    myType := reflect.TypeOf(mt)

    name := myType.Field(0)

    tag := name.Tag.Get("json")

    println(tag)

}

创建方式一:

package main

import "fmt"

type Teacher struct {  //定义结构体(类)

    Name  string

    //Age    int

    School string

    //或者这样定义: Name, School string

}

type IF interface {    //interface是一组函数的抽象,只能定义行为

    getName() string

}

func main() {

    var t1 Teacher    //将Teacher赋给t1

    fmt.Println(t1)

    t1.Name = "mashibing"

    t1.Age = 45

    t1.School = "qinghua"

    fmt.Println(t1)

    fmt.Println(t1.Age + 10)

}

创建方式二:

package main

import "fmt"

type Teacher struct {

    Name  string

    Age    int

    School string

}

func main() {

    var t Teacher = Teacher{}

    fmt.Println(t)

    t.Name = "mashibing"

    t.Age = 45

    t.School = "qinghua"

    fmt.Println(t)

}

创建方式三,指针:

package main

import "fmt"

type Teacher struct {

    Name  string

    Age    int

    School string

}

func main() {

    var t *Teacher = new(Teacher)

    (*t).Name = "mashibing"

    (*t).Age = 45

    t.School = "qinghua"  //也可以使用简化的方式,符合程序员的习惯

    fmt.Println(*t)

}

方式四:

package main

import "fmt"

type Teacher struct {

    Name  string

    Age    int

    School string

}

func main() {

    var t *Teacher = &Teacher{}

    (*t).Name = "mashibing"

    t.Age = 45

    t.School = "qinghua"

    fmt.Println(*t)

}

方法:作用在接受者上的函数

func (recv receiver_type) methodName(parameter_list) (return_value_list)

package main

import "fmt"

//定义结构体

type Person struct {

    Name string

}

//给Person结构体绑定方法test

func (p Person) test() {

    fmt.Println(p.Name)

}

func main() {

    var p Person //创建结构体对象

    p.Name = "lili"

    p.test()

}

工厂模式:解决跨包访问结构体小写问题

封装:

继承:

package main

import (

    "fmt"

)

// 定义动物结构体

type Animal struct {

    Age    int

    Weight float32

}

// 给Animal绑定方法:喊叫

func (an *Animal) Shout() {

    fmt.Println("大声喊叫")

}

// 给Animal绑定方法:自我展示

func (an *Animal) ShowInfo() {

    fmt.Printf("动物的年龄是:%v, 动物的体重是: %v", an.Age, an.Weight)

}

// ---------上面是一个父类,下面开始定义猫或狗来继承,go里叫做加入匿名结构体

// 定义结构体: Cat

type Cat struct {

    //为了复用性,体现继承思维,加入匿名结构体

    Animal

}

// 对Cat绑定特有的方法

func (c *Cat) scratch() {

    fmt.Println("我是小猫,我可以挠人")

}

func main() {

    //创建Cat结构体示例,以下的Animal可以去掉

    cat := &Cat{}

    cat.Animal.Age = 3

    cat.Animal.Weight = 10.6

    cat.Animal.Shout()

    cat.Animal.ShowInfo()

    cat.scratch()

}

接口:

接口定义一组方法集合

type IF interface {

    Method1(param_list) return_type

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Go 语言没有像Java那样的 try/catch 异常机制,它不能执行抛异常操作,而是使用了panic 和 re...
    副班长国伟阅读 6,338评论 0 1
  • 一、函数定义 函数是结构化编程中最小的模块单元,日常开发过程中,将复杂的算法过程分解为若干个小任务(代码块),使程...
    副班长国伟阅读 10,203评论 0 3
  • Go语言中,也和C或者其他语言一样,我们可以声明新的类型,作为其它类型的属性或字段的容器。 结构体定义 type ...
    副班长国伟阅读 4,367评论 0 1
  • 第一个程序HelloWorld 按照国际惯例,我们来实现helloworld package main标注程序位置...
    Joey_coder阅读 4,035评论 0 3
  • title: go语言入门date: 2019-02-12 22:03:27 前言 因项目需要和个人喜好,决定系统...
    dounine阅读 2,607评论 0 3

友情链接更多精彩内容