Go语言中如何通过方法为类型添加行为
作者:huangz/blog 发布时间:2024-01-31 18:02:10
前言
数十年以来, 传统的面向对象语言总是说方法属于类, 但 Go 不是这样做的: 它提供了方法, 但是并没有提供类和对象。 乍一看, 这种做法似乎有些奇怪, 甚至可以说有点儿疯狂, 但实际上 Go 的方法比以往其他语言的方法都要灵活。
使用 kelvinToCelsius 、 celsiusToFahrenheit 、 fahrenheitToCelsius 、 celsiusToKelvin 这样的函数虽然也能够完成温度转换工作, 但是通过声明相应的方法并把它们放置到属于自己的地方, 能够让温度转换代码变得更加简洁明了。
我们可以将方法与同一个包中声明的任何类型相关联, 但是不能为 int 和 float64 之类的预声明类型关联方法。 其中, 声明类型的方法在前面已经介绍过了:
type kelvin float64
kelvin 类型跟它的底层类型 float64 具有相同的行为, 我们可以像处理浮点数那样, 对 kelvin 类型的值执行加法运算、乘法运算以及其他操作。 此外, 声明一个将 kelvin 转换为 celsius 的方法就跟声明一个具有同等作用的函数一样简单——它们都以关键字 func 开头, 并且函数体跟方法体完全一样:
func kelvinToCelsius(k kelvin) celsius { // kelvinToCelsius 函数
return celsius(k - 273.15)
}
func (k kelvin) celsius() celsius { // kelvin 类型的 celsius 方法
return celsius(k - 273.15)
}
如图 13-1 所示, celsius 方法虽然没有接受任何形参, 但它的名字前面却有一个类似形参的接收者。 每个方法和函数都可以接受多个形参, 但一个方法必须并且只能有一个接收者。 在 celsius 方法体中, 接收者的行为就跟其他形参一样。
图 13-1 方法声明
除声明语法有些许不同之外, 调用方法的语法与调用函数的语法也不一样:
var k kelvin = 294.0
var c celsius
c = kelvinToCelsius(k) // 调用 kelvinToCelsius 函数
c = k.celsius() // 调用celsius方法
跟调用其他包中的函数一样, 调用方法也需要用到点记号。 以上面的代码为例, 在调用方法的时候, 程序首先需要给出正确类型的变量, 接着是一个点号, 最后才是被调用方法的名字。
既然温度转换操作现在已经是 kelvin 类型的方法, 那么继续使用 kelvinToCelsius 这样的名字就没有必要了。 在同一个包里面, 如果一个名字已经被函数占用了, 那么这个包就无法再定义同名的类型, 因此在使用函数的情况下, 我们将无法使用 celsius 函数返回 celsius 类型的值。 然而, 如果我们使用的是方法, 那么每种温度类型都可以具有自己的 celsius 方法, 就像以下展示的 fahrenheit 类型一样:
type fahrenheit float64
// celsius方法会将华氏度转换为摄氏度
func (f fahrenheit) celsius() celsius {
return celsius((f - 32.0) * 5.0 / 9.0) }
通过让每种温度类型都具有相应的 celsius 方法以转换为摄氏温度, 我们可以创造出一种完美的对称。
来源:https://blog.huangz.me/2020/type-method-in-go.html


猜你喜欢
- 情况1:Go语言中,若在子go程中创建一个新 go程,子go程释放(销毁),新创建的go程不会随着子go程的销毁而销毁。原因:go程共享堆,
- 本文研究的主要是Python使用requests发送POST请求的相关内容,具体介绍如下。一个http请求包括三个部分,为别为请求行,请求报
- 引用是什么在 PHP 中引用意味着用不同的名字访问同一个变量内容。这并不像 C 的指针,替代的是,引用是符号表别名。注意在 PHP 中,变量
- 下面先给大家介绍下Python3 执行系统命令并获取实时回显最近在改造一些打包的逻辑,原来在 Windows 下是基于批处理制作的,由于批处
- 1 通过System.DBNull判断,网上大部分都使用这个方法。DataTable dt;
- 无论使用int还是varchar,对于Status的多选查询都是不易应对的。举例,常规思维下对CustomerStatus的Enum设置如下
- 为了查找这些存储过程,你可以花时间在互联网搜索,查看一些你还未知道的存储过程,也许在一两个小时您可能会发现你想要...也许你很幸运的找到,其
- 概述你可能在JavaScript项目中都用了console.log。这是一种查看变量的值或程序运行中发生的事情的便捷方法。但是JavaScr
- 本文实例为大家分享了Python 12306抢火车票的具体代码,供大家参考,具体内容如下# -*- coding: utf-8 -*-fro
- Fuko Masked 是 Kaloyan Tsvetkov 的一个小型PHP库,用于通过用编辑后的元素替换列入黑名单的元素来屏蔽敏感数据。
- 首先想说的是它的安全性,这方面确实能让我感受到它的良苦用心。这主要可以分为两点:一、防范跨站伪造请求(Cross-site request
- 1 Tenacity描述今天 给大家介绍一个Python 重试库,Tenacity 这个库 是我 这些年 使用的一个非常好的库,几乎满足了我
- 前言JavaScript语言中有一个非常重要又难以掌握,近似神话的概念-闭包。对于有一点JavaScript使用经验但从未真正理解闭包概念的
- 一、算法构造1.简单介绍一下knn算法KNN算法,也叫K最近邻算法。功能是分类。算法逻辑非常简单,说直白点就是:先找到跟你最近的k个邻居(假
- 作业备份,不是备份数据库,是备份作业。 我的方法是把作业导出成文件备份起来,因为当你服务器维护的多了的时候很多你的作业 就很成问题,很麻烦。
- 闭包的概念我们尝试从概念上去理解一下闭包。在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部函数引用了外部函数的变量,则可能产生闭
- Pandas提供了duplicated、Index.duplicated、drop_duplicates函数来标记及删除重复记录duplic
- 本篇介绍Python中的引用。首先想一想如图示例。在python中,值是靠引用来传递来的。用id()来判断两个变量是否为同一个值的引用。如图
- 目录项目介绍已有功能环境安装Windows用看这里ubuntu用户看这里使用方式:主要代码项目地址项目介绍可以下载doc,ppt,pdf.对
- 具体代码和说明如下:upload.asp<form action=http://<%= Request.&n