go语言方法之方法声明

        从我们的理解来讲,一个对象其实也就是一个简单的赋值或者一个变量,在这个对象中会包含一些方法,而一个方法则是一个一个和特殊类型关联的函数。一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这些事情。

        在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。

package main

import (
	"fmt"
	"math"
)

type Point struct{ X, Y float64 }

// traditional function
func Distance(p, q Point) float64 {
	return math.Hypot(q.X-p.X, q.Y-p.Y)
}

// same thing, but as a method of the Point type
func (p Point) Distance(q Point) float64 {
	return math.Hypot(q.X-p.X, q.Y-p.Y)
}

func main() {
	p := Point{1, 2}
	q := Point{4, 6}
	fmt.Println(Distance(p, q)) 
	fmt.Println(p.Distance(q))  
}

5
5

Process finished with the exit code 0

 

        上面的代码里面有个附加参数p,叫做方法的接收器(receiver),早期的面向对象语言留下的遗产将调用一个方法称为“向一个对象发送消息”。

        在Go语言中,我们并不会像其他语言那样用this或者self作为接收器,我们可以任意的选择接收器的名字。由于接收器的名字经常会被使用到,所以保持其在方法间传递的一致性和简短性是不错的主意。这里的建议是可以使用其类型的第一个字母,比如这里使用了Point的首字母p。

        在方法调用过程中,接收器参数一般会在方法名之前出现。这种方法声明是一样的,都是接收器参数在方法名字之前。

        上图中的两个函数都是调用的distance,但是却没有发生冲突。第一个distance的调用实际上用的是包级别的函数main.Distance,而第二个则是使用刚刚声明的Point,调用的是Point类下声明的Point.Distance方法。

        这种p.Distance的表达式叫做选择器,因为他会选择合适的对应p这个对象的Distance方法来执行。选择器也会被用来选择一个struct类型的字段,比如p.X。由于方法和字段都是在同一命名空间,所以如果我们在这里声明一个X方法的话,编译器会报错,因为在调用p.X时会有歧义。

        因为每种类型都有其他方法的命名空间,我们在用Distance这个名字的时候,不同的Distance调用指向了不同类型的Distance方法。让我们来定义一个Path类型,这个Path代表一个线段 的集合,并且也给这个Path定义一个叫Distance的方法。

        

// A Path is a journey connecting the points with straight lines.
type Path []Point
// Distance returns the distance traveled along the 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
}

        Path是一个命名的slice类型,而不是Point那样的struct类型,然而我们依然可以为它定义方法。在能够给任意类型定义方法这一点上,Go和很多其它的面向对象的语言不太一样。因此 在Go语言里,我们为一些简单的数值、字符串、slice、map来定义一些附加行为很方便。方法可以被声明到任意类型,只要不是一个指针或者一个interface。

        两个Distance方法有不同的类型。他们两个方法之间没有任何关系,尽管Path的Distance方法 会在内部调用Point.Distance方法来计算每个连接邻接点的线段的长度。 让我们来调用一个新方法,计算三角形的周长:

perim := Path{
    {1, 1},
    {5, 1},
    {5, 4},
    {1, 1},
}
fmt.Println(perim.Distance()) // "12"

        在上面两个对Distance名字的方法的调用中,编译器会根据方法的名字以及接收器来决定具体 调用的是哪一个函数。第一个例子中path[i-1]数组中的类型是Point,因此Point.Distance这个 方法被调用;在第二个例子中perim的类型是Path,因此Distance调用的是Path.Distance。 Go语言圣经 方法声明 211 对于一个给定的类型,其内部的方法都必须有唯一的方法名,但是不同的类型却可以有同样 的方法名,比如我们这里Point和Path就都有Distance这个名字的方法;所以我们没有必要非 在方法名之前加类型名来消除歧义,比如PathDistance。这里我们已经看到了方法比之函数 的一些好处:方法名可以简短。当我们在包外调用的时候这种好处就会被放大,因为我们可 以使用这个短名字,而可以省略掉包的名字,下面是例子:

import "gopl.io/ch6/geometry"

perim := geometry.Path{{1, 1}, {5, 1}, {5, 4}, {1, 1}}
fmt.Println(geometry.Path.Distance(perim)) // "12", standalone function
fmt.Println(perim.Distance()) // "12", method of geometry.Path

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/658101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云计算-Lambda事件 (Lambda Events)

检索事件信息 (Retrieving Event Information) 在上一个主题中,我们已经看到了如何创建一个Lambda函数、添加handler、添加触发器和配置执行策略。在本主题中,我们将对其进行扩展。到目前为止,我们看到的handler应用非常简单,但我…

STM32_HAL_使用FPEC实现闪存的读写

STM32的FLASH结构 主存储器(Main Memory):这是STM32中最大的存储区域,用于存储用户的程序代码、常量数据以及程序运行时不变的数据。STM32的主存储器通常被组织为多个扇区(sector),每个扇区的大…

项目十三:搜狗——python爬虫实战案例

根据文章项目十二:简单的python基础爬虫训练-CSDN博客的简单应用,这一次来升级我们的技术,那么继续往下看,希望对技术有好运。 还是老样子,按流程走,一条龙服务,嘿嘿。 第一步:导入…

git 学习随笔

git 学习随笔 基本概念 git 对待数据类似快照流的形式而不是类似 cvs 那样的纪录文件随时间逐步积累的差异 git 中所有数据在存储钱都会计算校验和(hash) 三种状态:已提交(committed),已修改(modified),已暂存(staged)。 add…

20240528解决飞凌的OK3588-C的核心板可以刷机不能连接ADB的问题

20240528解决飞凌的OK3588-C的核心板可以刷机不能连接ADB的问题 2024/5/28 16:34 OS:Linux R4/Buildroot 硬件接了3条线出来,一直可以刷机,但是链接ADB异常。 【总是链接不上】 Z:\OK3588_Linux_fs\kernel\arch\arm64\boot\dts\rockchip\OK3…

防火墙如何端口映射?

防火墙端口映射(Firewall Port Mapping)是一种网络技术,通过对防火墙配置进行调整,允许外部网络用户访问内部网络中的指定端口。该技术使得外部用户可以通过公共网络访问内部网络中的特定服务或应用程序,从而实现远程访…

HackTheBox-Machines--Beep

Beep测试过程 1 信息收集 nmap端口扫描 gryphonwsdl ~ % nmap -sC -sV 10.129.137.179 Starting Nmap 7.94 ( https://nmap.org ) at 2024-05-28 14:39 CST Nmap scan report for 10.129.229.183 Host is up (0.28s latency). Not shown: 988 closed tcp ports (conn-refused…

【微服务】部署mysql集群,主从复制,读写分离

两台服务器做如下操作 1.安装mysqldocker pull mysql:5.72.启动以及数据挂载 mkdir /root/mysql/data /root/mysql/log /root/mysql/conf touch my.conf //mysql的配置文件docker run --name mysql \ -e MYSQL_ROOT_PASSWORD123456 \ -v /root/mysql/data:/var/lib/mysql \ -v…

FaceChain-FACT:开源10秒写真生成,复用海量LoRa风格,基模友好型写真应用

github开源地址:https://github.com/modelscope/facechain/tree/main/facechain_adapter 魔搭创空间应用体验:魔搭社区 一、效果演示 FaceChain FACT的代码和模型目前已经在github和modelscope创空间上同步开源。FaceChain FACT具有简单的交互式界面设…

Rohm公司参展欧洲PCI盛会

​德国历史悠久的文化名城纽伦堡,即将迎来一场科技盛宴——欧洲PCI展览会。在这个为期三天的盛会中(6月11日至13日),Rohm公司将以璀璨之姿,特别聚焦宽带隙(WBG)设备的璀璨光芒。 此次&#xff0…

linux安装srs

获取srs cd /opt git clone -b 4.0release https://gitee.com/ossrs/srs.git cd srs/trunk 启动srs ./objs/srs -c conf/srs.conf ./etc/init.d/srs status 访问http://192.168.220.146:8080/出现下方图片说明安装成功 点击进入SRS控制台看到下方图片

AI视频教程下载:使用ChatGPT进行商务写作

你将学到什么? 学习如何将ChatGPT集成到你的写作过程中,并有效地将其用作商务写作的个人写作助手。 学习如何使用ChatGPT生成想法,提高你的书面沟通的结构、清晰度和连贯性。 你将学习使用ChatGPT的最佳实践,包括如何自定义其设…

【Flutter】显式动画

🔥 本文由 程序喵正在路上 原创,CSDN首发! 💖 系列专栏:Flutter学习 🌠 首发时间:2024年5月29日 🦋 欢迎关注🖱点赞👍收藏🌟留言🐾 目…

k8s群集调度之 pod亲和 node亲和 标签指定

目录 一 调度约束 1.1K8S的 List-Watch 机制 ⭐⭐⭐⭐⭐ 1.1.1Pod 启动典型创建过程 二、调度过程 2.1Predicate(预选策略) 常见的算法 2.2priorities(优选策略)常见的算法 三、k8s将pod调度到指定node的方法 3.1指…

FPGA中的乒乓操作

为什么不直接选用一个缓存更大的FIFO而选用乒乓操作为什么乒乓操作可以实现低速处理高速数据乒乓操作适用哪些场景 一、乒乓操作结构 首先先介绍一下乒乓操作的原理,其结构如下: 输入选择单元负责将数据送到数据缓冲模块,然后输出选择单元负…

网络工程师---第四十三天

1、网络地址转换请简述DNS服务器迭代查询与递归的区别? 2、请从技术方面简述RAIDO、RAID1、RAID3、 RAID5的特点? 3、请从层次结构、部署设备和功能配置方面描述层次化的网络结构? 4、请简述IPSECVPN和AH和ESP的区别? 5、请简述ID…

用友U8 Cloud linkntb.jsp SQL注入漏洞复现(CNVD-C-2023-708748)

0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP,主要聚焦成长型、创新型企业,提供企业级云ERP整体解决方案。 0x02 漏洞概述 用友U8 Cloud linkntb.jsp 接口处存在SQL注入漏洞,未授权的攻击者可通过此漏洞获取数据库权限,从而盗取用户数据,造成用户信息泄露。 0x…

vue组件的基本使用方法

组件 【1】组件是什么? 组件就是:扩展 HTML 元素,封装可重用的代码,目的是复用例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html组件把js,cs…

[java基础揉碎]文件IO流

目录 文件 什么是文件 文件流​编辑 常用的文件操作 创建文件方式一 创建文件方式二 创建文件方式三 tip:为什么new file 了还有执行createNewFile?new File的时候其实是在内存中创建了文件对象, 还没有在磁盘中, 当执行createNewFile的时候才是往磁盘中写入​编辑 …

Golang 创建第一个web项目(Gin + Gorm)

1. 写这篇博客的由来: 当你想使用最快的框架创建项目的时候是不是有点束手无策? 当你想配置数据库写 SQL 甚至不知道如何写,文件夹都不知道建在哪里? 😄因为Golang 目前并没有 JAVA 那种硬性规范,但是…