设为首页 加入收藏

TOP

Go语言学习笔记(四)结构体struct & 接口Interface & 反射reflect(一)
2018-10-19 15:54:10 】 浏览:769
Tags:语言学习 笔记 结构 struct 接口 Interface 反射 reflect

加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959

结构体struct

struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套;

go中的struct类型理解为类,可以定义方法,和函数定义有些许区别;

struct类型是值类型

struct定义

type User struct {
    Name string
    Age  int32
    mess string
}
var user User
var user1 *User = &User{}
var user2 *User = new(User)

struct使用

下面示例中user1和user2为指针类型,访问的时候编译器会自动把 user1.Name 转为 (*user1).Name

func main() {
    var user User
    user.Name = "nick"
    user.Age = 18
    user.mess = "lover"

    var user1 *User = &User{
        Name: "dawn",
        Age:  21,
    }
    fmt.Println(*user1)                    //{dawn 21 }
    fmt.Println(user1.Name, (*user1).Name) //dawn dawn

    var user2 *User = new(User)
    user2.Name = "suoning"
    user2.Age = 18
    fmt.Println(user2)                     //&{suoning 18 }
    fmt.Println(user2.Name, (*user2).Name) //suoning suoning
}

构造函数

golang中的struct没有构造函数,可以伪造一个

type User struct {
    Name string
    Age  int32
    mess string
}

func NewUser(name string, age int32, mess string) *User {
    return &User{Name:name,Age:age,mess:mess}
}

func main() {
    //user := new(User)
    user := NewUser("suoning", 18, "lover")
    fmt.Println(user, user.mess, user.Name, user.Age)
}

内存布局

struct中的所有字段在内存是连续的,布局如下:

    var user User
    user.Name = "nick"
    user.Age = 18
    user.mess = "lover"

    fmt.Println(user)                   //{nick 18 lover}
    fmt.Printf("Name:%p\n", &user.Name) //Name:0xc420016180
    fmt.Printf("Age: %p\n", &user.Age)  //Age: 0xc420016190
    fmt.Printf("mess:%p\n", &user.mess) //mess:0xc420016198 8字节为内存对齐

方法

方法是作用在特定类型的变量上,因此自定义类型,都可以有方法,而不仅仅是struct。

方法的访问控制也是通过大小写控制。

init函数是通过传入指针实现,这样改变struct字段值,因为是值类型。

type User struct {
    Name string
    Age  int
    sex  string
}

func (this *User) init(name string, age int, sex string) {
    this.Name = name
    this.Age = age
    this.sex = sex
}

func (this User) GetName() string {
    return this.Name
}

func main() {
    var user User
    user.init("nick", 18, "man")
    //(&user).init("nick", 18, "man")
    name := user.GetName()
    fmt.Println(name)
}

匿名字段

如果有冲突的, 则最外的优先

type User struct {
    Name stirng
    Age int        
}

type Lover struct {
     User
     sex time.Time
     int
     Age int
}

继承 & 多重继承

一个结构体继承多个结构体,访问通过点。继承字段以及方法。

可以起别名,如下面 u1(user1),访问 user.u1.Age。

如果继承的结构体都拥有同一个字段,通过user.name访问就会报错,必须通过user.user1.name来访问。

type user1 struct {
    name string
    Age  int
}

type user2 struct {
    name string
    age  int
    sex time.Time
}

type User struct {
    u1   user1 //别名
    user2
    Name string
    Age  int
}

func main() {
    var user User
    user.Name = "nick"
    user.u1.Age = 18
    fmt.Println(user)    //{{ 18} { 0 {0 0 <nil>}} nick 0}
}

tag

在go中,首字母大小写有特殊的语法含义,小写包外无法引用。由于需要和其它的系统进行数据交互,例如转成json格式。这个时候如果用属性名来作为键值可能不一定会符合项目要求。tag在转换成其它数据格式的时候,会使用其中特定的字段作为键值。

import "encoding/json"

type User struct {
    Name string `json:"userName"`
    Age  int    `json:"userAge"`
}

func main() {
    var user User
    user.Name = "nick"
    user.Age = 18
    
    conJson, _ := json.Marshal(user)
    fmt.Println(string(conJson))    //{"userName":"nick","userAge":0}
}

String()

如果实现了String()这个方法,那么fmt默认会调用String()。

type name1 struct {
    int
首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Go语言学习笔记(一)Let's .. 下一篇go: GOPATH entry is relative; m..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目