zoukankan      html  css  js  c++  java
  • 结构体——方法和接收器,为任意类型添加方法

    1、方法和接收器

    在Go语言中,结构体就像是类的一种简化形式,那么类的方法在哪里呢?在Go语言中有一个概念,它和方法有着同样的名字,并且大体上意思相同,Go 方法是作用在接收器(receiver)上的一个函数,接收器是某种类型的变量,因此方法是一种特殊类型的函数。

    接收器类型可以是(几乎)任何类型,不仅仅是结构体类型,任何类型都可以有方法,甚至可以是函数类型,可以是 int、bool、string 或数组的别名类型,但是接收器不能是一个接口类型,因为接口是一个抽象定义,而方法却是具体实现,如果这样做了就会引发一个编译错误invalid receiver type…。

    接收器也不能是一个指针类型,但是它可以是任何其他允许类型的指针,一个类型加上它的方法等价于面向对象中的一个类,一个重要的区别是,在Go语言中,类型的代码和绑定在它上面的方法的代码可以不放置在一起,它们可以存在不同的源文件中,唯一的要求是它们必须是同一个包的。

    类型 T(或 T)上的所有方法的集合叫做类型 T(或 T)的方法集。

    因为方法是函数,所以同样的,不允许方法重载,即对于一个类型只能有一个给定名称的方法,但是如果基于接收器类型,是有重载的:具有同样名字的方法可以在 2 个或多个不同的接收器类型上存在,比如在同一个包里这么做是允许的

    在面向对象的语言中,类拥有的方法一般被理解为类可以做的事情。在Go语言中“方法”的概念与其他语言一致,只是Go语言建立的“接收器”强调方法的作用对象是接收器,也就是类实例,而函数没有作用对象。

    接收器的格式如下:

    func (接收器变量 接收器类型) 方法名(参数列表) (返回参数) {
        函数体
    }

    对各部分的说明:

    • 接收器变量:接收器中的参数变量名在命名时,官方建议使用接收器类型名的第一个小写字母,而不是 self、this 之类的命名。例如,Socket 类型的接收器变量应该命名为 s,Connector 类型的接收器变量应该命名为 c 等。
    • 接收器类型:接收器类型和参数类似,可以是指针类型和非指针类型。
    • 方法名、参数列表、返回参数:格式与函数定义一致。

    接收器根据接收器的类型可以分为指针接收器、非指针接收器,两种接收器在使用时会产生不同的效果,根据效果的不同,两种接收器会被用于不同性能和功能要求的代码中。

    1)指针类型的接收器

    指针类型的接收器由一个结构体的指针组成,更接近于面向对象中的 this 或者 self。
    由于指针的特性,调用方法时,修改接收器指针的任意成员变量,在方法结束后,修改都是有效的。

    示例:

    package main
    import "fmt"
    
    type Property struct {
    	value int
    }
    
    func (p *Property) SetValue(v int) {
    	p.value = v
    }
    
    func (p *Property) Value() int {
    	return p.value
    }
    func main() {
    	p := new(Property)
    	p.SetValue(100)
    	fmt.Println(p.Value())
    }
    

      

    2)非指针类型的接收器

    当方法作用于非指针接收器时,Go语言会在代码运行时将接收器的值复制一份,在非指针接收器的方法中可以获取接收器的成员值,但修改后无效。

    示例:

    package main
    import (
    	"fmt"
    )
    
    type Point struct {
    	X int
    	Y int
    }
    
    func (p Point) Add(other Point) Point {
    	return Point{p.X + other.X, p.Y + other.Y}
    }
    func main() {
    	p1 := Point{1, 1}
    	p2 := Point{2, 2}
    	result := p1.Add(p2)
    	fmt.Println(result)
    }
    

      

    3)指针和非指针接收器的使用

    在计算机中,小对象由于值复制时的速度较快,所以适合使用非指针接收器,大对象因为复制性能较低,适合使用指针接收器,在接收器和参数间传递时不进行复制,只是传递指针。

    2、为任意类型添加方法

    Go语言可以对任何类型添加方法,给一种类型添加方法就像给结构体添加方法一样,因为结构体也是一种类型。

    示例:

    package main
    import (
    	"fmt"
    )
    // 将int定义为MyInt类型
    type MyInt int
    
    func (m MyInt) IsZero() bool {
    	return m == 0
    }
    
    func (m MyInt) Add(other int) int {
    	return other + int(m)
    }
    func main() {
    	var b MyInt
    	fmt.Println(b.IsZero())
    	b = 1
    	fmt.Println(b.Add(2))
    }
    

      

  • 相关阅读:
    Civil 3D 二次开发 创建Civil 3D 对象—— 01 —— 创建几何空间点
    Civil 3D 二次开发 创建Civil 3D 对象—— 00 ——
    Civil 3D 二次开发 创建AutoCAD对象—— 01 —— 创建直线
    Civil 3D 二次开发 新建CLR项目出现错误C2143
    Civil 3D 二次开发 创建AutoCAD对象—— 00 ——
    了解AutoCAD对象层次结构 —— 6 ——块表记录
    datepicker97使用
    使用angular 外接 templateUrl,使用ng-include
    angularJs 遮罩
    网上找的有关css兼容问题
  • 原文地址:https://www.cnblogs.com/ACGame/p/11922546.html
Copyright © 2011-2022 走看看