Go结构体类型的使用

老人与海&欧加琪 作品

我们花了两年学会说话,却要花上六十年来学会闭嘴。 by 佚名

引用于:http://wufazhuce.com/one/1384

结构体定义

type identifier struct {
    field1 type1
    field2 type2
    ...
}

使用 new 初始化结构体

使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针:var t *T = new(T)或者t := new(T),另外,用&T{},也同样等价于用new,因为底层仍然会调用new(T)

type Point struct {
    x int
    y int
}

func Test_demo1(t *testing.T) {
    intr1 := new(Point)
    intr1.x = 2
    intr1.y = 6
    intr2 := &Point{0, 3}
    intr3 := &Point{x: 5, y: 1}
    intr4 := &Point{y: 5}

    fmt.Println(intr1) //&{2 6}
    fmt.Println(intr2) //&{0 3}
    fmt.Println(intr3) //&{1 5}
    fmt.Println(intr4) //&{0 5}
}
使用 new 初始化
结构体字面量初始化

实例化结构体两种常用形式:
1:用 new(T) 实例化。
2:用 &T{} 实例化。(推荐)

使用工厂模式创建结构体实例

func NewPoint(x int, y int) *Point {
    if x < 0 || y < 0 {
        return nil
    }
    return &Point{x, y}
}

func Test_demo2(t *testing.T) {
    p1 := NewPoint(-1, 2)
    fmt.Println(p1) //nil

    p2 := NewPoint(2, 2)
    fmt.Println(p2) //&{2 2}
}

上面的示例演示的就是工厂模式创建结构体实例,在Go标准包有很多地方应用的该模式。可以把这种模式等同为面向对象语言中的构造函数。另外,如果把 Point 结构体,命名变成小写,即point,就可以作为私有变量,强制实例化结构体必须使用工厂模式。

反射获取结构体的标签

type Point struct {
    x int "this is x"
    y int "this is y"
}

func Test_demo3(t *testing.T) {
    //p := &Point{1, 2} //会报运行时错误
    p := Point{1, 2}
    pType := reflect.TypeOf(p)
    pField := pType.Field(0) 
    fmt.Printf("%v\n", pField.Tag) //this is x
}

结构体的方法

一个类型加上它的方法等价于面向对象中的一个类。通常情况下,这个类型一般定义为结构体类型。

定义方法的格式

func (recv receiver_type) methodName(parameter_list) (return_value_list) { ... }

其中,recv可称之为这个方法methodName接收者receiver_type接收者类型。该类型可以是除了interface类型的任何类型,但是通常都用结构体类型。

在接收者是指针时,方法可以改变接收者的值(或状态),当然这点函数也可以做到(当参数作为指针传递,即通过引用调用时,函数也可以改变参数的状态)。但如果接受者不是指针,方法是无法改变接收者的状态的,方法内部应用的接收者状态,仅是接收者实例的拷贝

指针方法和值方法都可以在指针或非指针上被调用,Go会自动转换。

type Info struct {
    address string
    phone string
}

//接收者是非指针
func (this Info) changeInfo() {
    this.address = "上海"
    this.phone = "10086"
    fmt.Println(this)
}

//接收者是指针
func (this *Info) changeInfo2() {
    this.address = "上海"
    this.phone = "10086"
    fmt.Println(this)
}

func Test_demo5(t *testing.T) {
    info := &Info{"北京", "10086"}
    //指针调用,但接收者自动被转换成了非指针,changeInfo函数应用的是info的拷贝。
    info.changeInfo() // {上海 10086}
    fmt.Println(info) //&{北京 10086}

    info2 := Info{"北京", "10086"}
    //非指针调用,但接收者自动被转换成了指针,changeInfo函数应用的是真正的info实例。
    info2.changeInfo2() // &{上海 10086}
    fmt.Println(info2) //{上海 10086}
}

在 Test_demo5 中第一种调用接收者是指针类型,但调用changeInfo方法时,Go自动转换成非指针类型,即实例的拷贝,所以在方法体内的改变Info的属性值,其实修改的是拷贝版,原实例并不受影响。而第二种调用接收者是非指针类型,但是Go自动转换成指针类型,所以内部的修改会影响实例本身属性状态。

所以:**如果想通过方法改变接收者实例本身的属性值或者状态,那么方法的接收者必须是指针类型。

结构体方法定义的常用规范:
*func (this T) methodName(parameter_list) (return_value_list) { ... }

类的公有/私有属性和方法

Go规定命名的属性如果首字母大写,即可以被非本go文件程序调用。所有公有的属性和方法,命名首字母必须大写。反之,便是私有的。

类的继承

type Human struct {
    Name string
}

func (this *Human) eat() {
    fmt.Println(this.Name + "要吃饭.")
}

type Man struct {
    Human //继承了Human类
}

func (this *Man) chageName(name string) {
    this.Name = name
}

func Test_demo6(t *testing.T) {
    man := &Man{Human{"人类"}}
    man.chageName("男人")
    man.eat() //男人要吃饭.
}

读取运行内存

func Test_demo7(t *testing.T) {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    fmt.Printf("%d Kb\n", m.Alloc/1024) //单位Kb
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,635评论 0 9
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,295评论 18 399
  • 支出:5 晚上停水,明天办公室停电,停电干嘛上班嘛!电脑不能用,大家坐在办公室干瞪眼嘛! 梅雨天要来了,抽湿器用起来哦!
    没错我就是那个帅小伙阅读 156评论 1 0
  • 求助 :react-native init Demo 成功了,但虚拟机报错!!! 环境:Mac air 系统10....
    清心_49a5阅读 2,542评论 1 0