go 结构体 (struct) 和方法 (method)

结构体(struct)

go中没有对象这一律念,因此采用告终构体的概念,结构体在go中有着很是重要的位置。结构体是值类型,因此可使用new函数来建立。结构体中字段必须惟一。微信

结构体定义以下:ide

type identifier struct {
    filed type
    filed type
}
复制代码

filed就是结构体的字段名字,type是字段的类型,若是暂时不知道命名,可使用 _ 来进行占位。字段可使用任何类型,甚至是结构体自己,也能够是函数或者接口。 通常来讲,给结构体的字段赋值这样便可:函数

var s T
s.a = 1
s.b = 2
复制代码

使用new函数给一个新的结构体变量分配内存,返回已分配内存:ui

var t *T = new(T)
// or
t := new(T)
复制代码

例子:spa

type Person struct {
    Name string
    Age  int
    Sex  int
}

func main() {
    person := new(Person)
    person.Name = "Tim"
    person.Age  = 10
    person.Sex  = 1
    
    //or
    
    person := &Person{"Tim", 10 , 1}
    
    fmt.Println(person)
}

// 输出 &{Tim, 10, 1}

复制代码

就像面向对象语言那样,可使用点来给字段进行赋值,一样的也能够经过点来进行获取字段的值。指针

结构体一样能够做为参数进行传递:code

func getPersonName(p *Person) string {
    return p.Name
}

func main() {
    ...
    
    fmt.Prinltn(getPersonName(person))
}
// 输出 Tim
复制代码

若是想知道一个结构体占用了多少内存,可使用:cdn

size := unsafe.Sizeof(T{}}
复制代码

结构体中除了字段和类型外,还有一个可选的标签,一个字段的辅助字符串,只有reflect能获取它。对象

例子:索引

type Person struct {
    Name string "Name"
    Age  int    "Age"
    Sex  int    "Sex"
}

func main() {
    person := Person{}
    person.Name = "Tim"
    person.Age  = 10
    person.Sex  = 1
    
    for i := 0; i < 3; i++ {
        refTag(person, i)
    }
}

func refTag(p Person, i int) {
    pType := reflect.TypeOf(p)
    iFiled := pType.Filed(i)
    fmt.Println(iFiled.Tag)
}

//out 
复制代码

reflect.TypeOf能够获取变量的正确类型,若是变量是一个结构体,就能够经过Filed来索引该结构体的字段,而后就可使用Tag属性。

go结构体还支持一个特殊字段,匿名字段。这些字段没有显式的名字,只有字段类型,此时字段类型也就是字段的名字,匿名字段也能够是一种结构体。

例子:

type Test1 struct {
    t1 int
    t2 int
}

type Test struct {
    a int
    b string
    bool
    Test1
}

func main() {
    test := new(Test)
    test.a = 1
    test.b = "2"
    test.bool = true
    test.t1 = 2
    test.t2 = 3
    
    fmt.Println(test)
}

//out &{1, "2", true, 2, 3}
复制代码

经过test.bool的名字来获取匿名字段的数据,因而能够得出一个结论,在一个结构体中对于每一种数据类型只能有一个匿名字段。 在结构体内嵌结构体是,若是遇到命名冲突可是又都须要保留时,可使用:

Test.Test1.Filed
复制代码

这样使用就避免了命名冲突。

方法

go方法是做用在接收者上的一个函数,接收者是某种类型的变量,所以方法是一种类型的函数。接收者类型几乎能够任何类型,指针类型和函数类型就不行。 由于方法是函数,因此方法不能被重载,对于一个类型只有一个既定名称的方法。 定义方法的格式以下:

func (r receiver_type) methodName(parmeter_list) (value_list){
    ...
}
复制代码

r是receiver_type的实例,methodName是r的方法名,调用也很简单,r.methodName() 便可。 例子:

type Person struct {
    Name string
    Age  int
}

func (p *Person) GetName() string {
    return p.Name
}

func (p *Person) GetAge() int {
    return p.Age
}

func main() {
    p := new(Person)
    p.Name = "1"
    p.Age  = 2
    
    fmt.Prinltn(p.GetName())
    fmt.Prinltn(p.GetAge())
}

// out "1" 2
复制代码

微信搜索「goentry-xyz」,关注公众号「灯下独码」

相关文章
相关标签/搜索