golang学习之struct

结构体定义的一般方式如下:

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

type T struct {a, b int} 也是合法的语法,它更适用于简单的结构体。

var t *T
t = new(T)

变量 t 是一个指向 T的指针,此时结构体字段的值是它们所属类型的零值,使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针。

无论变量是一个结构体类型还是一个结构体类型指针,都使用同样的 选择器符(selector-notation) 来引用结构体的字段,即:

type myStruct struct { i int }
var v myStruct    // v是结构体类型变量
var p *myStruct   // p是指向一个结构体类型变量的指针
v.i
p.i

struct实例:

package main

import (
    "fmt"
    "strings"
)

type Person struct {
    firstName string
    lastName  string
}

func upPerson(p *Person) {
    p.firstName = strings.ToUpper(p.firstName)
    p.lastName = strings.ToUpper(p.lastName)
}

func main() {

    // 1-struct as a value type:
    var pers1 Person
    pers1.firstName = "Chris"
    pers1.lastName = "Woodward"
    upPerson(&pers1)
    fmt.Printf("The name of the person is %s %s\n", pers1.firstName, pers1.lastName)

    // 2—struct as a pointer:
    pers2 := new(Person)
    pers2.firstName = "Chris"
    pers2.lastName = "Woodward"
    (*pers2).lastName = "Woodward" // 这是合法的
    upPerson(pers2)
    fmt.Printf("The name of the person is %s %s\n", pers2.firstName, pers2.lastName)

    // 3—struct as a literal:
    pers3 := &Person{"Chris", "Woodward"}
    upPerson(pers3)
    fmt.Printf("The name of the person is %s %s\n", pers3.firstName, pers3.lastName)
}

程序输出:

The name of the person is CHRIS WOODWARD
The name of the person is CHRIS WOODWARD
The name of the person is CHRIS WOODWARD

使用反射访问struct的tag标签:

package main

import (
    "fmt"
    "reflect"
)

type Person struct {
    firstName string `An important answer`
    lastName  string `The name of the thing`
}

func main() {

    tt := Person{"first", "last"}
    for i := 0; i < 2; i++ {
        refTag(tt, i)
    }
}

程序输出:

Tag:An important answer    Name:firstName
Tag:The name of the thing    Name:lastName

在值和指针上调用方法:

可以有连接到类型的方法,也可以有连接到类型指针的方法。

但是这没关系:对于类型 T,如果在 *T 上存在方法 Meth(),并且 t 是这个类型的变量,那么 t.Meth() 会被自动转换为(&t).Meth()

指针方法和值方法都可以在指针或非指针上被调用,收者类型是 *TwoInts 的方法 AddThem(),它能在类型 TwoInts 的值上被调用,这是自动间接发生的。

因此 two2.AddThem 可以替代 (&two2).AddThem()

再说一句,go中有方法继承与覆盖,不过必须是匿名字段o

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏LinkedBear的个人空间

设计模式笔记(五)——代理模式 原

通过实现一个与被代理对象的类相同的接口,完成被代理对象的实际方法调用。(接口性多态)

633
来自专栏Spark学习技巧

Scala语言基础之结合demo和spark讲实现链式计算

一,什么是链式计算 1,一般开发习惯把事情封装到一个方法中;链式编程思想是把要做的事情封装到block中,给外部提供一个返回这个block的方法 2,链式编程思...

2177
来自专栏跟着阿笨一起玩NET

C#构造函数里的base和this的区别

父类的构造函数总是在子类之前执行的。既先初始化静态构造函数,后初始化子类构造函数。

801
来自专栏性能与架构

认识一下 Java 11

可能很多人现在 Java8 的新特性还没用熟呢,Java 11 就已经来了,下面一起来看下 Java 11 的几个新特性:

912
来自专栏PhpZendo

带你入门 JavaScript ES6 (三)

上一章我们学习了 for of 遍历和扩展字符语法。本章我们主要学习 ES6 中的箭头函数

502
来自专栏GreenLeaves

C# 数组基础

一、数组的基础知识 1、数组有什么用? 如果需要同一个类型的多个对象,就可以使用数组。数组是一种数组结构,它可以包含同一个类型的多个元素. 2、数组的初始化方式...

2207
来自专栏码云1024

C#反射

2693
来自专栏程序你好

理解C#语言中相等Equality 和唯一 Identity

792
来自专栏大内老A

谈谈Nullable<T>的类型转换问题

本篇文章讨论可空值类型(Nullable<T>)的转换,却确地说是如何将一种类型的值对象转换成相应的可空值。这来源于今天我们的一个成员遇到的一个小问题,我经过一...

18210
来自专栏Java技术栈

屌炸天,JDK8的排序大法!!

首先祝大家端午节快乐! 今天总结了下JDK中排序的方法,包括JDK8中强大的lambda表达式及函数式接口运用,不废话,请看下面示例。 public class...

2516

扫码关注云+社区