Golang初级系列教程-Struct

Golang初级系列教程-Struct

Go 是面向对象语言吗

对于接受过面向对象思想的用户首先需要声明一点:Go 中没有 class 关键字。关键字 struct 是一个集大成者。JavaC#C++ 以及其它语言都支持 struct。其中一些支持 struct 中包含方法。Go 也支持,而且提供更多的功能。

在一些面向对象语言中,方法是 class 或者 struct 中存在的,在 Go 中只有 struct

Java 部分代码

class House {
    public String getHouseName() {  //method defined within class
        //implementation
    }
}

Go 部分代码

type House struct { }

func (h House) GetHouseName() string { } //method defined outside of struct, but works on House

虽然在 Go 中没有面向对象的概念,但是通过 struct 的一些特性,类似的功能特性也是可以实现的。结构体通过关键字 typestruct 定义。

type my_struct_name struct { }

type Rectangle struct { }

type Vehicle struct { }

type Vehicle1_Car struct { }

上面的定义都符合 Go 变量定义的规则,都是有效的语句。下面几个则不正确。

type Hash# struct {} //cannot have special characters
type 0struct struct {} //cannot start with a number

另外,结构体中可以包含其它数据。所以,如同类一样,可以在结构体中定义任何想要展现的数据,以此来安排结构体在内存中的存放空间。以下是一些正确的例子。

type my_struct_name struct {
    i int
    j int
    s string
}

type Rectangle struct {
    length, width int //you can define multiple items of the same type on the same line separated by commas
    area float64
}

至此,我们可以利用上面定义的 Rectangle,访问其属性。

package main

import "fmt"

type Rectangle struct {
    length, width int
}

func main() {
    r := Rectangle{}  
    fmt.Println("Default rectangle is: ", r) //print default zero-ed value
}
Default rectangle is: {0 0}

通过上面的输出可以看出:结构体中的变量如果没有初始化,是自动赋值为 zero-value,即 int 类型赋值为 0string 类型赋值为 ""。所以对于结构体而言,其 zero-value 是由其内部属性决定的。

在下面的例子中,展示通过不同的方式初始化结构体的内部属性,并且将其打印到标准输出。

package main

import "fmt"

type Rectangle struct {
    length, width int
    name string
}

func main() {
    r1 := Rectangle{2, 1, "my_r1"} //initialize values in order they are defined in struct
    fmt.Println("Rectangle r1 is: ", r1)

    r2 := Rectangle{width:3, name:"my_r2", length:4} //initialize values by variable name in any order
    fmt.Println("Rectangle r2 is: ", r2)

    pr := new (Rectangle) //get pointer to an instance with new keyword
    (*pr).width = 6 //set value using . notation by dereferencing pointer.  
    pr.length = 8 //set value using . notation - same as previous.  There is no -> operator like in c++. Go automatically converts
    pr.name = "ptr_to_rectangle"
    fmt.Println("Rectangle pr as address is: ", pr) //Go performs default printing of structs
    fmt.Println("Rectangle pr as value is: ", *pr) //address and value are differentiated with an & symbol
}
Rectangle r1 is: {2 1 my_r1}
Rectangle r2 is: {4 3 my_r2}
Rectangle pr as address is: &{8 6 ptr_to_rectangle}
Rectangle pr as value is: {8 6 ptr_to_rectangle}

通过以上的例子,需要注意以下几点:

  • 通过 {} 可以初始化属性值,注意赋值时是按照声明的顺序通过 , 分割。r1 := Rectangle{2, 1, "my_r1"}
  • 也可以通过 变量名:值 的形式赋值。r2 := Rectangle{width:3, name:"my_r2", length:4}
  • 通过关键字 new 可以获得一个对象的指针。
  • 获得的指针,访问属性石,* 操作符是可以不需要。
  • Go 根据其结构体的属性,提供默认的打印机制。

结构体和变量的封装和可见性

其它语言有 publicprotectedprivate 等声明属性和方法对于不同上下文的可见性。在遇见 Go 之前,我觉得这样的设计无可厚非。Go 对于可见性的支持如此简单,一开始你可能认为这个设计太拙劣了。废话少说,在 Go 中,如果变了的首字母大写,即表明对于外包是可见的。嗯,就这么简单。

type notExported struct { //this struct is visible only in this package as it starts with small letter
}

type Exported struct { //variable starts with capital letter, so visible outside this package
    notExportedVariable int //variable starts with small letter, so NOT visible outside package
    ExportedVariable int //variable starts with capital letter, so visible outside package
    s string //not exported
    S string //exported
}  

你可能会说,这是啥?是啥?而我要说,这简直是天才的设计啊。如此简单,如此明朗,不在需要任何额外的关键字。同时,通过查看某个变量的首字母就可以瞬间知道它的可见性,而无需在去费时去查找。其它语言,可能有一些对变量的规定来实现这种功能。但是 Go 将其发扬光大。


Golang一种神奇的语言,让我们一起进步

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值