Go语言中如何通过方法为类型添加行为
前言
数十年以来, 传统的面向对象语言总是说方法属于类, 但 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 方法以转换为摄氏温度, 我们可以创造出一种完美的对称。
总结
到此这篇关于Go语言中如何通过方法为类型添加行为的文章就介绍到这了,更多相关Go语言通过方法为类型添加行为内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
相关推荐
-
GO语言基本类型分析
本文实例分析了GO语言基本类型.分享给大家供大家参考.具体如下: 一.整型 go语言有13种整形,其中有2种只是名字不同,实质是一样的,所以,实质上go语言有11种整形.如下: (1)int :依赖不同平台下的实现,可以是int32或int64 (2)int8 : (-128->127) (3)int16: (-32768->32767) (4)int32: (-2 147 483 648->2 147 483 647) (5)int64 :(-9 223 372 036 854 77
-
Go语言的方法接受者类型用值类型还是指针类型?
概述 很多人(特别是新手)在写 Go 语言代码时经常会问一个问题,那就是一个方法的接受者类型到底应该是值类型还是指针类型呢,Go 的 wiki 上对这点做了很好的解释,我来翻译一下. 何时使用值类型 1.如果接受者是一个 map,func 或者 chan,使用值类型(因为它们本身就是引用类型). 2.如果接受者是一个 slice,并且方法不执行 reslice 操作,也不重新分配内存给 slice,使用值类型. 3.如果接受者是一个小的数组或者原生的值类型结构体类型(比如 time.Time 类
-
为什么Go语言把类型声明放在后面?
关于类型,官网上有一段仔细地介绍了一下函数指针的部分,现在的设计比起 C 的语法,清晰很多. 也就是说,类型放在后面是为了更加清晰易懂.Rob Pike 曾经在 Go 官方博客解释过这个问题(查看原文:Go's Declaration Syntax),简略翻译如下(水平有限翻译的不对的地方见谅): 引言 Go语言新人常常会很疑惑为什么这门语言的声明语法(declaration syntax)会和传统的C家族语言不同.在这篇博文里,我们会进行一个比较,并做出解答. C 的语法 首先,先看看 C 的
-
Go语言基础知识总结(语法、变量、数值类型、表达式、控制结构等)
一.语法结构 golang源码采用UTF-8编码.空格包括:空白,tab,换行,回车. - 标识符由字母和数字组成(外加'_'),字母和数字都是Unicode编码. - 注释: 复制代码 代码如下: /* This is a comment; no nesting */ // So is this. 二.字面值(literals)类似C语言中的字面值,但数值不需要符号以及大小标志: 复制代码 代码如下: 23 0x0FF 1.234e7类似C中的字符串,但字符串是Unicode/UTF-8编码的
-
Go语言基本的语法和内置数据类型初探
Go令牌 Go程序包括各种令牌和令牌可以是一个关键字,一个标识符,常量,字符串文字或符号.例如,下面的Go语句由六个令牌: 复制代码 代码如下: fmt.Println("Hello, World!") 个体令牌是: 复制代码 代码如下: fmt . Println ( "Hello, World!" ) 行分离器 在Go程序,行的分隔符关键是一个语句终止.也就是说,每一个单独语句不需要特殊的分隔线; 在C编译器转到内部的地方; 作为语句终止符,表示一个逻辑实体的结
-
GO语言类型转换和类型断言实例分析
本文实例讲述了GO语言类型转换和类型断言的用法.分享给大家供大家参考.具体分析如下: 由于Go语言不允许隐式类型转换.而类型转换和类型断言的本质,就是把一个类型转换到另一个类型. 一.类型转换 (1).语法:<结果类型> := <目标类型> ( <表达式> ) (2).类型转换是用来在不同但相互兼容的类型之间的相互转换的方式,所以,当类型不兼容的时候,是无法转换的.如下: 复制代码 代码如下: func test4() { var var1 int = 7
-
Go语言中的复合类型详细介绍
golang复合类型包括:结构体.数组.切片.Maps. 1.数组 数组 golang中的数组与C语言中的数组差异很大,倒更类似Pascal中的数组. (Slice,下个话题,有些像C语言中的数组) 复制代码 代码如下: var ar [3]int 声明ar为一个拥有三个整型数的数组,所有元素初始化为0. 大小是类型的一个组成部分. 内置的函数len可以用于获取数组大小: 复制代码 代码如下: len(ar) = 3 数组是值类型 golang中的数组是值,而非C语言中的隐式指针.你可以获得数组
-
GO语言基本数据类型总结
本文实例总结了GO语言基本数据类型.分享给大家供大家参考.具体如下: 1.注释(与C++一样) 行注释://块注释:/* ...*/ 2.标识符 可以这么说,除了数字开头的不允许,符号开头的不允许,关键字不允许,其他的Unicode字符组合都可以."_33"也可以是标识符."我们"也可以是标识符.标识符也区分大小写. (1).以大写字母开头的标识符是公开的.(这个很有意思) (2).其他任何标识符都是私有的. (3).空标识符"_"是一个占位符,
-
Go语言中如何通过方法为类型添加行为
前言 数十年以来, 传统的面向对象语言总是说方法属于类, 但 Go 不是这样做的: 它提供了方法, 但是并没有提供类和对象. 乍一看, 这种做法似乎有些奇怪, 甚至可以说有点儿疯狂, 但实际上 Go 的方法比以往其他语言的方法都要灵活. 使用 kelvinToCelsius . celsiusToFahrenheit . fahrenheitToCelsius . celsiusToKelvin 这样的函数虽然也能够完成温度转换工作, 但是通过声明相应的方法并把它们放置到属于自己的地方, 能够让
-
Kotlin 语言中调用 JavaScript 方法实例详解
Kotlin 语言中调用 JavaScript 方法实例详解 Kotlin 已被设计为能够与 Java 平台轻松互操作.它将 Java 类视为 Kotlin 类,并且 Java 也将 Kotlin 类视为 Java 类.但是,JavaScript 是一种动态类型语言,这意味着它不会在编译期检查类型.你可以通过动态类型在 Kotlin 中自由地与 JavaScript 交流,但是如果你想要 Kotlin 类型系统的全部威力 ,你可以为 JavaScript 库创建 Kotlin 头文件. 内联 J
-
Go语言中常量定义方法实例分析
本文实例讲述了Go语言中常量定义方法.分享给大家供大家参考.具体分析如下: 常量的定义与变量类似,只不过使用 const 关键字. 常量可以是字符.字符串.布尔或数字类型的值. 复制代码 代码如下: package main import "fmt" const Pi = 3.14 func main() { const World = "世界" fmt.Println("Hello", World) fmt.Printl
-
Go语言中结构体方法副本传参与指针传参的区别介绍
GO语言结构体方法跟结构体指针方法的区别 首先,我定了三个接口.一个结构和三个方法: type DeptModeA interface { Name() string SetName(name string) } type DeptModeB interface { Relocate(building string, floor uint8) } type Dept struct { name string building string floor uint8 Key string } fun
-
go语言中函数与方法介绍
在C#或者Java里面我们都知道,一个Class是要包含成员变量和方法的,对于GO语言的Struct也一样,我们也可以给Struct定义一系列方法. 一.怎么定义一个方法? Go的方法是在函数前面加上一个接收者,这样编译器就知道这个方法属于哪个类型了.例如: package demo1 import ( "fmt" ) type Student struct { Name string Age int Class string } func (stu Student) GetUserI
-
C语言中字符串与各数值类型之间的转换方法
C语言的算法设计中,经常会需要用到字符串,而由于c语言中字符串并不是一个默认类型,其标准库stdlib设计了很多函数方便我们处理字符串与其他数值类型之间的转换. 首先放上一段展示各函数使用的代码,大家也可以copy到自己的机器上运行观察 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int num=183; char str[3]; //itoa函数将整型转换为字符串数值类型 it
-
c语言中缺省参数的类型总结
1.函数全缺省参数,函数在定义或者声明时,所有的形参都默认值. #include <stdio.h> //x,y为函数的形参,如果函数被调用时,没有设置x和y值,x值默认为100,y值默认为5 int sub(int x=100,int y=5) { return (x-y); } int main(void) { int a=20; int b=10; //变量a.b为sub函数的实参 printf("sub函数计算结果 = %d\n",sub(a, b)); //注意:
-
go语言方法集为类型添加方法示例解析
目录 1概述 2为类型添加方法 2.1基础类型作为接收者 2.2结构体作为接收者 3值语义和引用语义 4方法集 4.1类型 *T 方法集 4.2类型 T 方法集 5匿名字段 5.1方法的继承 5.2方法的重写 6方法值和方法表达式 6.1方法值 6.2方法表达式 1概述 在面向对象编程中,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些函数,这种带有接收者的函数,我们称为方法(method).本质上,一个方法则是一个和特殊类型关联的函数. 一个面向对象的程序会用方法来表达其属性
-
C语言中各种运算类型全面总结
目录 一.概述 二.四则运算 三.关系运算 四.逻辑运算与位运算 五.深度剖析位运算 一.概述 C语言中支持下面4种类型的运算 运算类型 运算符 四则运算 +,-,*,/,% 关系运算 <,>,<=,>=,==,!= 逻辑运算 &&,||,! 位运算 &,|,^,>>,<<,~ 二.四则运算 (+,-,*,/,%) 就是数学中的加,减,乘,除等运算 遵循先乘除后加减的运算优先级 可以使用括号改变运算顺序 注意: C语言中的除法运算,其
-
C语言中的参数传递机制详解
C中的参数传递 本文尝试讨论下C中实参与形参的关系,即参数传递的问题. C语言的参数传递 值传递 首先看下列代码: #include <stdio.h> int main(){ int n = 1; printf("实参n的值:%d,地址:%#x\n", n, &n); void change(int i);//函数声明 change(n); printf("函数调用后实参n的值:%d,地址:%#x\n", n, &n); return
随机推荐
- 详解vue父子模版嵌套案例
- Echarts基本用法_动力节点Java学院整理
- 动态加载js、css等文件跨iframe实现
- 实现DataGridView控件中CheckBox列的使用实例
- 详解Yii2 rules 的验证规则
- php连接MySQL的两种方式对比
- VB中的RasEnumConnections函数返回632错误解决方法
- Android 使用Shell脚本截屏并自动传到电脑上
- Android自定义TextView实现drawableLeft内容居中
- js 纯数字不重复排列的另类方法
- JavaScript实现复制功能各浏览器支持情况实测
- 世界上最NB的人!
- 表单类各种类型(文本框)失去焦点效果jquery代码
- jQuery EasyUI NumberBox(数字框)的用法
- JS处理VBArray的函数使用说明
- Centos6.x服务器配置jdk+tomcat+mysql环境(jsp+mysql)
- Nginx中IF语句实现数学比较功能
- 实例详解Java实现图片与base64字符串之间的转换
- C#实现的MD5加密功能与用法示例
- 常用的php对象类型判断