首页 > 其他分享 >大数据开发:Go中的方法

大数据开发:Go中的方法

时间:2022-11-09 16:00:23浏览次数:57  
标签:func int 声明 Book 开发 Go 方法 pages

我们知道Go中没有继承,接口的用法也与Java中的用法大相径庭,很多适合,我们需要使用OO的思想来组织我们达到项目,但是将Java的oo思想在Go中会比较痛苦,Go中的方法和面向对象的类似,但是定义上也是很多初学者不好理解的,比如方法的定义竟然在结构体外部,组装起来看起来也很随意,其实Go只是有面向对象特性,其实不算是面向对象语言。

方法

Go支持一些面向对象编程特性,方法是这些所支持的特性之一。 本篇文章将介绍在Go中和方法相关的各种概念

方法声明

在Go中,我们可以为类型T*T显式地声明一个方法,其中类型T必须满足四个条件:

  1. T必须是一个定义类型

  2. T必须和此方法声明定义在同一个代码包中;

  3. T不能是一个指针类型;

  4. T不能是一个接口类型。

类型T*T称为它们各自的方法的属主类型(receiver type)。 类型T被称作为类型T*T声明的所有方法的属主基类型(receiver base type)

如果我们为某个类型声明了一个方法,以后我们可以说此类型拥有此方法,一个方法声明和一个函数声明很相似,但是比函数声明多了一个额外的参数声明部分。 此额外的参数声明部分只能含有一个类型为此方法的属主类型的参数,此参数称为此方法声明的属主参数(receiver parameter)。 此属主参数声明必须包裹在一对小括号()之中。 此属主参数声明部分必须处于func关键字和方法名之间

下面是一个方法声明的例子:

// Age和int是两个不同的类型。我们不能为int和*int
// 类型声明方法,但是可以为Age和*Age类型声明方法。
type Age int
func (age Age) LargerThan(a Age) bool {
  return age > a
}
func (age *Age) Increase() {
  *age++
}

// 为自定义的函数类型FilterFunc声明方法。
type FilterFunc func(in int) bool
func (ff FilterFunc) Filte(in int) bool {
  return ff(in)
}

// 为自定义的映射类型StringSet声明方法。
type StringSet map[string]struct{}
func (ss StringSet) Has(key string) bool {
  _, present := ss[key]
  return present
}
func (ss StringSet) Add(key string) {
  ss[key] = struct{}{}
}
func (ss StringSet) Remove(key string) {
  delete(ss, key)
}

// 为自定义的结构体类型Book和它的指针类型*Book声明方法。
type Book struct {
  pages int
}
func (b Book) Pages() int {
  return b.pages
}
func (b *Book) SetPages(pages int) {
  b.pages = pages
}

每个方法对应着一个隐式声明的函数

对每个方法声明,编译器将自动隐式声明一个相对应的函数。 比如对于上一节的例子中为类型Book*Book声明的两个方法,编译器将自动声明下面的两个函数:

func Book.Pages(b Book) int {
  return b.pages // 此函数体和Book类型的Pages方法体一样
}

func (*Book).SetPages(b *Book, pages int) {
  b.pages = pages // 此函数体和*Book类型的SetPages方法体一样
}

在上面的两个隐式函数声明中,它们各自对应的方法声明的属主参数声明被插入到了普通参数声明的第一位。 它们的函数体和各自对应的显式方法的方法体是一样的

两个隐式函数名Book.Pages(*Book).SetPages都是aType.MethodName这种形式的。 我们不能显式声明名称为这种形式的函数,因为这种形式不属于合法标识符。这样的函数只能由编译器隐式声明。 但是我们可以在代码中调用这些隐式声明的函数

方法原型(method prototype)和方法集(method set)

一个方法原型可以看作是一个不带func关键字的函数原型。 我们可以把每个方法声明看作是由一个func关键字、一个属主参数声明部分、一个方法原型和一个方法体组成

方法值和方法调用

方法事实上是特殊的函数。方法也常被称为成员函数。 当一个类型拥有一个方法,则此类型的每个值将拥有一个不可修改的函数类型的成员(类似于结构体的字段)。 此成员的名称为此方法名,它的类型和此方法的声明中不包括属主部分的函数声明的类型一致。 一个值的成员函数也可以称为此值的方法。

一个方法调用其实是调用了一个值的成员函数。假设一个值v有一个名为m的方法,则此方法可以用选择器语法形式v.m来表示。

下面这个例子展示了如何调用为Book*Book类型声明的方法:

package main

import "fmt"

type Book struct {
  pages int
}

func (b Book) Pages() int {
  return b.pages
}

func (b *Book) SetPages(pages int) {
  b.pages = pages
}

func main() {
  var book Book

  fmt.Printf("%T \n", book.Pages)       // func() int
  fmt.Printf("%T \n", (&book).SetPages) // func(int)
  // &book值有一个隐式方法Pages。
  fmt.Printf("%T \n", (&book).Pages)    // func() int

  // 调用这三个方法。
  (&book).SetPages(123)
  book.SetPages(123)           // 等价于上一行
  fmt.Println(book.Pages())    // 123
  fmt.Println((&book).Pages()) // 123
}

和普通参数传参一样,属主参数的传参也是一个值复制过程。 所以,在方法体内对属主参数的直接部分的修改将不会反映到方法体外

参考

吴邪,小三爷,混迹于后台,大数据,人工智能领域的小菜鸟。

标签:func,int,声明,Book,开发,Go,方法,pages
From: https://www.cnblogs.com/xyou/p/16874013.html

相关文章

  • 2022 年你需要掌握的 7 种关于 JavaScript 的数组方法(下)
    4.Array.forEach()现在这是一个经典。那个 forEach() 方法的工作原理很像常规 for 循环。它在数组上循环并对每个项目执行一个函数。 .forEach() 的第一个参数是......
  • 0009.Django请求与响应
    HttpRequest对象服务器接受到http协议的请求后,会根据报文创建HttpRequest对象视图函数的第一个参数是HttpRequest对象在django.http模型中定义了HttpRequest对象的API......
  • PHP WebService接口开发
    生成wsdl文件,php不能生成入参对象的形式,用java生成比较简单。安装IntelliJIDEAsdk:1.8(不要使用高版本)打开项目下载soap.zip,IDEA打开项目。左侧项目列表,右键项目......
  • django一些常用命令
    django一些常用命令#创建项目django-adminstartprojectmysite#创建app,创建成功项目以后,cd进入mysitepythonmanage.pystartappapp01#数据库迁移命令pythonmanage.p......
  • django-cors-headers实现跨域的方法总结
    django-cors-headers实现跨域的方法总结在setting.py中配置INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.cont......
  • Python|使用Tkinter进行GUI开发
    农带作业系列Tkinter简介什么是Tkinter?Tkinter是Python的标准GUI库。Python使用Tkinter可以快速的创建GUI应用程序。由于Tkinter是内置到python的安装包中,只要安装好......
  • 活动紧急插播 | QCon 全球软件开发者大会早班车连线分享
    今晚20:00-21:30,OpenMLDB社区运营负责人陆雨霄,QCon全球软件开发者大会早班车线上直播中以OpenMLDB为例和大家聊聊开源社区运营的难点。以OpenMLDB为例聊聊开源社区......
  • vue子组件修改父组件的方法
    父组件::floorPlanShow.sync="floorPlanShow"子组件:props:["floorPlanShow"];this.$emit("update:floorPlanShow",true);阻止冒泡和捕获@click.stop.capture......
  • 15~30K招聘视觉图像处理工程师,OpenCV/Halcon开发经验
    公司背景    南京黎创智能装备有限公司(以下简称“黎创智能装备”)是一家专注于工业机器人,机器视觉设备及自动化生产线设计研发、生产、销售与应用的科技型企业,依托物联网......
  • 更稳定的手势识别方法--基于手部骨架与关键点检测
    导读本期将介绍并演示基于MediaPipe的手势骨架与特征点提取步骤以及以此为基础实现手势识别的方法。介绍关于MediaPipe以前有相关文章介绍,可以参看下面链接:Google开源手势识......