Golang method 方法详解

Posted Wallace JW

tags: $.jBox.confirm 外层方法返回true    .net controller方法接收参数方式    .net core 前端传递一个array,后台接收方法    .net core 方法接收post请求参数中的某一变量    $http方法的详解   

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang method 方法详解相关的知识,希望对你有一定的参考价值。

前言
class结构体(struct)-方法(method)-接口(interface)method

文章目录

基本语法

接收器

接收器(receiver)
type
type testint int  //  使用 type 定义一种 testint 类型
func (a testint) test(b int) int  // test 方法为 testint 类型的方法
  	c := int(a) + b		// 类型转换
	return c


func main() 
	var a testint = 2
	fmt.Println(a.test(3)) // 5

声明和调用

下面用一段代码来说明方法和函数在声明和调用上的区别:

type Point struct 
	X float64
	Y float64


type Path []Point

// 函数
func Distance(p, q Point) float64 
    return math.Hypot(q.X-p.X, q.Y-p.Y)


// Point 类型的方法
func (p Point) Distance(q Point) float64 
    return math.Hypot(q.X-p.X, q.Y-p.Y)


// Path 类型的方法
func (path Path) Distance() float64 
	sum := 0.0
	for i := range path 
		if i > 0 
			sum += path[i-1].Distance(path[i])
		
	
	return sum


p := Point1, 2
q := Point4, 6
perim := Path
	1, 1,
	5, 1,
	5, 4,
	1, 1,


fmt.Println(Distance(p, q)) // "5", function call
fmt.Println(p.Distance(q))  // "5", method call Point.Distance
fmt.Println(perim.Distance()) // "12", method call Path.Distance

事实上,方法也是一种函数,只是把接收器作为第一个入参而已。

fmt.Printf("%T\\n", Point.Distance)		//func(Point, Point) float64
fmt.Printf("%T\\n", p.Distance)			// func(Point) float64

选择器

p.Distance(q)p.X选择器(selector)p.Distance(q)
X

基于指针对象的方法

由于方法也是一种函数,所以我们很容易理解方法也是通过值传递的方式来拷贝参数值,因此,和函数中的处理一样,如果我们想要在方法内对一个参数进行改变,则必须使用指针对象来作为方法的接收器,如:

func (p *Point) ScaleBy(factor float64) 
	p.X *= factor
	p.Y *= factor


r := &Point1, 2
r.ScaleBy(2)
fmt.Println(*r) // "2, 4"

// 注意,由于临时变量的内存地址无法获取,所以不能使用下面这种写法
Point1, 2.ScaleBy(2) // compile error: can't take address of Point literal
(*Point).ScaleBy(*Point)Point

一个很容易出错的点在于,我们需要使用一个类型的指针来作为接收器,而不能使用指针类型本身来作为接收器,举个例子:

func (p *Point) f1()   // 正确

type PP *Point
func (pp PP) f2()   // 编译错误

f2 这种写法会报编译错误

invalid receiver type PP (PP is a pointer type)
通过内嵌结构体扩展方法
p.Distance(q)p.X
import "image/color"

type Point struct 
	X float64
	Y float64 


type ColoredPoint struct 
	Point
	Color color.RGBA


red := color.RGBA255, 0, 0, 255
blue := color.RGBA0, 0, 255, 255
var p = ColoredPointPoint1, 1, red
var q = ColoredPointPoint5, 4, blue
fmt.Println(p.Distance(q.Point)) // "5"

可以看到,即使 ColoredPoint 类型没有声明 Distance 方法,也可以直接当作 Point 类型方法的接收器来使用。类比于其他的 OOP 语言,可以将 Point 看做基类,将 ColoredPoint 看做继承它的子类来理解。

但是必须强调以下两点:

  1. 继承只是一种理解方法,和继承思想最大的不同是,ColoredPoint 只是拥有 Point 成员并且可以使用它的字段和方法,但是 ColoredPoint 并不是 Point 类型,因此,ColoredPoint 虽然可以作为 Point 方法的接收器,但是并不能作为 Point 类型的参数使用,下列写法会报错。
p.Distance(q) // compile error: cannot use q (ColoredPoint) as Point
  1. 只有内嵌结构体可以实现上述用法,如果是将 Point 类型的对象作为 ColorPoint 的字段,则不成立,以下写法会报错。
type ColoredPoint struct 
	point Point
	Color color.RGBA


fmt.Println(p.Distance(q.Point))
// 报错
// p.Distance undefined (type ColoredPoint has no field or method Distance)
// q.Point undefined (type ColoredPoint has no field or method Point, but does have point)
方法值

跟函数一样,方法也可以作为方法值使用,这种情况下调用时就不再需要指定接收器,如下:

p := Point1, 2
q := Point4, 6
distanceFromP := p.Distance // method value
fmt.Println(distanceFromP(q)) // "5"

以上是关于Golang method 方法详解的主要内容,如果未能解决你的问题,请参考以下文章