21天从Java转向Go之第七天——水滴石穿(方法)

方法

方法声明

  • 方法的声明和普通函数的声明类似,只是在函数名字前面多了一个参数。这个参数把这个方法绑定到这个参数对应的类型上。

接收者

  • 值接收者

  • 指针接收者

  • go语言即允许使用值,也允许使用指针来调用方法,Go会做隐式转换。值接收者使用值的副本来调用方法,而指针接受者使用实际值来调用方法。

  • nil是一个合法的接收者。就像允许一些函数允许nil指针作为实参,方法的接收者也一样,尤其是当nil是类型中有意义的零值(如map、slice),更是如此。

通过结构体内嵌组成类型

  • 子类接收者(包括值和指针)可以调用父类声明的方法,原因是编译器会自动为子类生成接收者类型是子类的方法

方法变量和方法表达式


m1 :=  p.scaleV2   //方法变量
m1(1.2)

m2 := Point.scale //方法表达式
m2(point,1.0)

封装

  • Go语言中封装的单元是包而不是类型,无论是函数内的代码还是方法内的代码,结构体类型内的字段对于同一个包中所有的代码都是可见的。

  • getter和setter函数。命名getter方法的时候通常将Get前缀省略。

package main


import (
   "fmt"
   "sync"
)

type Point struct {
   x, y float32
}

type ColorPoint struct {
   clolor int
   Point
}

func (p *Point) scale(factor float32) {
   p.x *= factor
   p.y *= factor

}

func (p Point) scaleV2(factor float32) {
   fmt.Println("scaleV2")

}

type circle *float32

//不允许对指针类型定义方法
//Invalid receiver type 'circle' ('circle' is a pointer type)
//func (c *circle) circlePi()  {
//
//}
//匿名结构体  cheche继承了Mutex的方法
var cache = struct {
   c  map[string]string
   sync.Mutex
}{c: make(map[string]string)}

func main() {

   cache.Lock()
   fmt.Println(cache.c[""])

   point := Point{x: 100, y: 50}

   (&point).scale(1.2) //120.00001 60.000004
   //如果接收者是指针,使用变量调用方法,会对变量做隐式转换&p
   point.scale(1.2) //144.00002 72.00001
   fmt.Println(point.x, point.y)

   //如果接收者是类型  使用指针去调用方法也是可以的 会隐式转换*P
   p := &point
   p.scaleV2(100.0)

   colorPoint := ColorPoint{100, Point{x: 1, y: 2}}
   colorPoint.scale(100)
   colorPoint.scaleV2(2)

   cache.Unlock()

   m1 :=  p.scaleV2   //方法变量
   m1(1.2)

   m2 := Point.scale //方法表达式
   m2(point,1.0)
}
原文地址:https://www.cnblogs.com/perkins/p/15624080.html