struct,interface,method
struct类型,值传递的
-
声明
struct { name string age int } //几种声明使用方式: var p person // p现在就是person类型的变量了 p.name = "astaxie" // 赋值"astaxie"给p的name属性. p.age = 25 // 赋值"25"给变量p的age属性 //按照顺序提供初始化值 p := person{"tom", 25} //通过field:value的方式初始化,这样可以任意顺序 p := person{age:24, name:"tom"} //当然也可以通过new函数分配一个指针,此处p的类型为*person p := new(person)
struct的匿名字段
struct定义的时候是字段名与其类型一一对应,实际上go支持只提供类型,而不写字段名的方式,也就是匿名字段,也称为嵌入字段。当匿名字段是一个struct的时候,那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct。
-
所有的内置类型和自定义类型都是可以作为匿名字段的
type human struct { age int phone string // human类型拥有的字段 } type student struct { human // 匿名字段,struct int // 内置类型作为匿名字段 phone string // 学生的phone字段 } //student访问属性age的时候,就像访问自己所有用的字段一样 //匿名字段能够实现字段的继承。 // 初始化学生jane jane := student{human:human{35, "777-444-xxxx"},phone:"666-444-xxxx"} // 修改匿名内置类型字段 jane.int = 3 //最外层的优先访问 //访问student里面的phone字段 fmt.println(jane.phone) // 如果我们要访问human的phone字段 fmt.println(jane.human.phone)
interface
-
定义interface
type interfacename interface { func1() func2() ...... }
interface类型定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。因此任意的类型都实现了空interface。
如果我们定义了一个interface的变量,那么这个变量里面可以存实现这个interface的任意类型的对象。所以空interface可以存储任意类型的数值。
一个函数把interface{}作为参数,那么他可以接受任意类型的值作为参数,如果一个函数返回interface{},那么也就可以返回任意类型的值。
嵌入interface如果一个interface1作为interface2的一个嵌入字段,那么interface2隐式的包含了interface1里面的method。
面向对象
method
-
method是附属在一个给定的类型上的,他的语法和函数的声明语法几乎一样,只是在func后面增加了一个receiver(也就是method所依从的主体)。语法如下:
func (**r receivertype)** funcname(parameters) (results)
- 虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样
- receiver可以是值和指针, 两者的差别在于, 指针作为receiver会对实例对象的内容发生操作,而普通类型作为receiver并不对原实例对象发生操作。
method能作用在任何你自定义的类型、内置类型、struct等各种类型上面。
指针作为receiver
如果一个method的receiver是*t,你可以在一个t类型的实例变量v上面调用这个method,而不需要&v去调用这个method
-
如果一个method的receiver是t,你可以在一个t类型的变量p上面调用这个method,而不需要 p去调用这个method
func (b *box) setcolor(c color) { b.color = c } //*b.color=c和b.color=c这两种方式都是正确的 //当你用指针去访问相应的字段时(虽然指针没有任何的字段) //go知道你要通过指针去获取这个值。 func (bl boxlist) paintitblack() { for i := range bl { bl[i].setcolor(black) } } //paintitblack里面调用setcolor的时候写成 //(&bl[i]).setcolor(black)和bl[i].setcolor(black)都可以 //因为setcolor的receiver是*box都可以,因为go知道receiver是指针,他自动帮你转了。
method继承
-
如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method。让我们来看下面这个例子
type human struct { name string age int phone string } type student struct { human //匿名字段 school string } type employee struct { human //匿名字段 company string } //在human上面定义了一个method func (h *human) sayhi() {a fmt.printf("hi, i am %s you can call me on %s\n", h.name, h.phone) } func main() { mark := student{human{"mark", 25, "222-222-yyyy"}, "mit"} sam := employee{human{"sam", 45, "111-888-xxxx"}, "golang inc"} mark.sayhi() sam.sayhi() }
method重写
//如果employee想要实现自己的sayhi //我们可以在employee上面定义一个method,重写了匿名字段的方法。 func (e *employee) sayhi() { fmt.printf("hi, i am %s, i work at %s. call me on %s\n", e.name,e.company, e.phone) }
参考书籍:
上一篇: 朋友圈微商月入百万背后的秘密,不是你想象中的那么有钱!
下一篇: JavaScript概述
推荐阅读
-
C#中实现Fluent Interface的三种方法
-
java中接口(interface)及使用方法示例
-
去掉Myeclipse对JS等文件的验证(Cannot return from outside a function or method)
-
C#接口interface用法实例
-
php采用curl访问域名返回405 method not allowed提示的解决方法
-
java abstract class interface之间的区别介绍
-
C#接口(Interface)用法分析
-
C#中实现Fluent Interface的三种方法
-
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
-
innodb_flush_method取值方法(实例讲解)