go - method方法

chuangrain · · 1749 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

method

1. 值与引用
  varName2 = varName1
  varName2.funcName()
  如果 varName2 有变化,varName1 无变化,则为值类型(传递)
  如果 varName2 有变化,varName1 有变化,则为引用类型(传递)

2. Method
  格式:
  func (r [*]ReceiverType) funcName(param) (result) {...}
  注:
  a. r 为struct对象的接收者,接收者不同,方法也不同
  b. r 可以为值传递也可以为引用传递
  c. param 和 result 可有可无,与普通函数一样
  d. 调用方法,用 "." 连接,即 r.funcName()
  e. func (r *ReceiverType) funcName()和 func (r ReceiverType) funcName 不能同时存在(此处funcName相同)
  f. method 可以用于所有的类型
  例:
type Circle struct {
  radius float64
}

func main() {
  var c1 Circle
  c1.radius = 10.00
  fmt.Println("Area of Circle(c1) = ", c1.getArea())
}

//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
  //c.radius 即为 Circle 类型对象中的属性
  return 3.14 * c.radius * c.radius
}

  用面向对象的方式表示,struct == class,struct 中声明的元素为成员属性,Circle 作为接收者的函数为成员方法
  即 Circle 类名,radius 与 getArea() 分别是 Circle 类对象 c1 的成员属性和成员方法
  例1 (值传递):
type Circle struct {
  radius float64
}

func main() {
  var c1 Circle
  c1.radius = 10.00
  fmt.Println("main(): radius = ", c1.radius)
  fmt.Println("Area of Circle(c1) = ", c1.getArea())
}

func (c Circle) getArea() float64 {
  fmt.Println("getArea(): radius = ", c.radius)
  return 3.14 * c.radius * c.radius
}

func (c Circle) setRadius(r float64) {
  c.radius = r
  fmt.Println("setRadius(): radius = ", c.radius)
}
  结果:
setRadius(): radius = 10
main(): radius = 0
getArea(): radius = 0
Area of Circle(c1) = 0

  例2 (引用传递)
type Circle struct {
  radius float64
}

func main() {
  var c2 Circle
  c2.setRadius(10.00)
  fmt.Println("main(): radius = ", c2.radius)
  fmt.Printf("Radius of Circle(c2) = %.2f, area = %.2f", c2.radius, c2.getArea())
}

func (c *Circle) setRadius(r float64) {
  c.radius = r
  fmt.Println("setRadius(): radius = ", c.radius)
}

func (c *Circle) getArea() float64 {
  fmt.Println("getArea(): radius = ", c.radius)
  return 3.14 * c.radius * c.radius
}
  结果:
setRadius(): radius = 10
main(): radius = 10
getArea(): radius = 10
Radius of Circle(c2) = 10.00, area = 314.00

  补:
  method可用于所有类型
  定义格式:
  type 自定义类型 类型
  如: type Integer int,类似于给 int 定义一个别名,但是此时的 Integer 与 struct 定义的类型使用方法一样,把它当作一个类,可以为其添加方法
  例:
type Integer int
func main() {
  var i Integer
  fmt.Println(i.getType())
  fmt.Println(Integer.getType(i))
  Integer.Print(i, "I am Int")
}

func (i Integer) getType() string {
  return "Integer == int"
}

func (i Integer) Print(s string) {
  fmt.Println(s)
}
  结果:
  Integer == int
  Integer == int
  I am Int

  注:
  a. 接收者为 typeName,而不是 *typeName 时,调用方法 varName.funcName(param) 与 typeName.funcName(varName, param) 一样,如果是 *typeName 则不能后者访问
  b. 如果者为 *typeName 时,通过 varName.funcName() 访问时,等于 (&varName).funcName(),即可以不用在 varName 前面加上 "&" 取地址

3. Method继承与重载
  匿名字段就类似于面向对象编程中的继承成员属性,也可以重载成员属性,method 同样可以继承和重载
  3.1 继承示例:
  类似于调用父类中有而子类中没有的方法
  没有面向对象中的private protected public关键字(通过方法名首字母大小写来判断)
type Person struct {
  name string
  age int
}

type Employee struct {
  Person
  salary int
}

func main() {
  // var em1 Employee = Employee{Person{"rain", 23}, 5000}
  em1 := Employee{Person{"Rain", 23}, 5000}
  em1.printMsg()
}

func (p Person) printMsg() {
  fmt.Println("I am ", p.name, " , and my age is ", p.age)
}
  结果:
  I am Rain , and my age is 23
  3.2 重载示例
  重载方法,通过 varName.funcName() 访问时,也采用最外层优先访问的原则,也类似于面向对象中调用本类中的方法
  通过 varName.匿名字段.funcName() 访问指定匿名字段中的方法,类似于面向对象中调用父类中的方法
type Person struct {
  name string
  age int
}

type Employee struct {
  Person
  salary int
}

func main() {
  // var em1 Employee = Employee{Person{"rain", 23}, 5000}
  em1 := Employee{Person{"Rain", 23}, 5000}
  em1.printMsg()       //调用最外层(本类)的方法
  em1.Person.printMsg()//调用指定匿名字段(父类)的方法
}

func (p Person) printMsg() {
  fmt.Println("I am ", p.name, " , and my age is ", p.age)
}

func (e Employee) printMsg() {
  fmt.Printf("I am %s, my age is %d, and my salary is %d. \n", e.name, e.age, e.salary)
}
  结果:
  {{rain 23} 5000}
  I am rain, my age is 23, and my salary is 5000.
  I am rain , and my age is 23

版权声明:本文为博主原创文章,未经博主允许不得转载。


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:chuangrain

查看原文:go - method方法

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1749 次点击  
加入收藏 微博
1 回复  |  直到 2000-01-01 00:00:00
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传