05 July 2018

内置数据类型

int
int64   
string  字符串
bool    布尔
Duration 时间间隔(纳秒)
资源类型

自定义数据类型

使用struct关键字来定义数据类型

//自定义user类型
type user struct {
    name   string
    age    int
    gander string
}

type admin struct {
    person user   //user类型的字段
    Level string
}
//申明一个user类型的变量bill
var bill user  

//申明并初始化mark,没有顺序要求
mark := user{
    age:18,
    name:"mark",
    gander:"male",
}

//申明并初始化jim,字段有顺序要求,必须更user类型字段顺序一致
jim := user{"jim",18,"male"}

//初始化manger
manger := admin{
    person : user{
            name:"jim",
            age:28,
            email: "jim@gmail.com",
        },
    level : "super",
}

基于一个已有的类型,自定义新的数据类型

//基于int64 申明Duration数据类型
type Duration int64
second := 129
fmt.Println(second)
在Duration类型的声明中,我们把int64 类型叫作Duration 的基础类型。不过,虽然int64 是基础类型,Go 并不认为Duration 和int64 是同一种类型。int64只能看作是Duration的基础类型,也就是说int64类型的值,不能当作Duration类型来用。编译器不会对不同类型的值做隐士转换。

自定义方法

方法能给用户定义的类型添加新的行为。方法实际上也是函数,只是在声明时,在关键字func 和方法名之间增加了一个(接收者)参数。
//定义user类型
type user struct {
    name string
    age int
}

//使用值接收者实现一个方法
func (u user) notify {
    fmt.Printf("show the person name %s and age %d", u.name, u.age)
}

//使用指针接收者实现一个方法
func (u *user) changeName(name string) {
    u.name = name
}

func (u *user) changeAge(age int) {
    u.age = age
}
//入口函数中调用
func main() {
    jim := &user{"jim", 18, "male"}
    <!-- 可以使用一个值来调用使用指针接收者声明的方法 -->
    jim.changeName("mark")  
    <!--(&jim).changeName("bill") -->
    jim.changeAge(20)
    jim.notify()
}

ps :Go语言里有两种类型的接收者:值接收者和指针接收者。如果是值接收者,调用时会使用这个值的副本来执行,而指针接受者使用实际值来调用方法。

类型的本质

如果给一个类型,添加或者删除某个值,是要创建一个新值,还是要更改当前的值?如果要创建一个新值,该类型的方法就使用值接收者,如果要修改当的值,就使用指针接收者。

接口

接口是用来定义行为的类型, 太抽象,直接看代码。

package main

import (
    "fmt"
)
//定义一个接口notifier
type notifier interface {
    notify()
}

type user struct {
    name string
    age int
}

//user类型的方法,用于被接口调用
func (u * user) notify() {
    fmt.Printf("show the person name %s and age %d\n", u.name, u.age)
}

//实现接口的方法
func sendNotify(n notifier){
    n.notify()
}
func main {
    u := user{"mark",28}
    //这里需要传递引用,因为notify方法是引用传递
    sendNotify(&u)
}

ps : 如果实现方法是传引用,就需要传引用的对象,如果方法是值传递,调用的时候传值和传引用都可以。

嵌入类型

package main

import (
    "fmt"
)
//定义一个接口notifier
type notifier interface {
    notify()
}

type user struct {
    name string
    age int
}

type Admin struct {
    user   //内嵌类型
    level string
}

//user类型的方法,用于被接口调用
func (u * user) notify() {
    fmt.Printf("show the person name %s and age %d\n", u.name, u.age)
}

//实现接口的方法
func sendNotify(n notifier){
    n.notify()
}
func main {
    // 创建一个admin 用户
    admin := admin{
        user : user {
            name : "jim mark",
            age : 30
        },
        level : "spuer"
    }
    // 我们可以直接访问内部类型的方法
    admin.user.notify()
    // 内部类型的方法也被提升到外部类型
    ad.notify()
}