Go 语言学习之 method
01
概念
method 和函数类似,只是在函数名字前面多了一个参数,这个参数把这个 method 绑定到这个参数对应的类型上。
函数名字前面多的这个参数,我们称之为 method 的接收者,接收者名字最好能够选择简短且在整个 method 中名称始终保持一致的名字。通常的做法是取类型名字的首字母作为接收者名字。
因为 method 和成员变量的字段同属于一个命名空间,所以在 struct 类型中成员变量的字段名不能和 method 名字相同。否则会报编译错误。
因为每个类型有它自己的命名空间,所以我们可以在其它不同类型中使用相同的 method 名字。
在 Go 语言中,除了指针类型和接口类型之外,在同一个包下的其他任何类型都可以声明 method。
实参接收者会复制整个实参变量,如果实参变量太大,或者我们需要更新接收者变量,我们可以使用指针传递变量的地址。
method 的接收者允许 nil 指针作为实参,尤其是 map 和 slice 类型,其零值就是 nil 的类型。
02
实参接收者的 method
通过代码,我们演示实参接收者的 method。
type user struct {
uid int
uname string
age uint16
}
func (u user) info() string {
str := fmt.Sprintf("I am %s, My id is %d, and my age is %d.n", u.uname, u.uid, u.age)
return str
}
func main() {
u := user{
uid: 1,
uname: "lucy",
age: 20,
}
userInfo := u.info()
fmt.Println(userInfo)
fmt.Println(u)
}
03
指针接收者的 method
通过代码,我们演示指针接收者的 method。
type user struct {
uid int
uname string
age uint16
}
func (u *user) eat() string {
str := fmt.Sprintf("I am %s, I am eating now.n", u.uname)
return str
}
func main() {
u1 := &user{
uid: 2,
uname: "lily",
age: 19,
}
eater := u1.eat()
fmt.Println(eater)
fmt.Println(*u1)
fmt.Println(u1)
}
提示:
在实际 Go 语言项目开发中,struct 类型的任何一个方法使用指针接收者,通常此类型的所有方法都应该使用指针接收者,不管方法需不需要使用指针接收者。
04
struct 内嵌匿名字段的 method
内嵌匿名字段可以方便地使用匿名字段的所有字段和方法,通过这种方式,可以组成复杂类型,每个匿名字段提供一些方法。
内嵌匿名字段可以是指向命名类型的指针,字段和方法间接地来自于指针指向的对象。
struct 类型可以拥有多个匿名字段,这个类型的值可以拥有所有字段的方法,和它自身声明的方法,在调用方法时,编译器选择方法的优先级从高往低依次是自身声明的方法、内嵌字段的方法、内嵌字段的内嵌字段的方法,在同一个层级有同名方法时,编译器会报错。
05
method 变量与 method表达式
method 变量是指将接收者的一个方法赋予一个变量,method 变量通常用于函数调用者期望函数的行为是调用一个特定接收者的 method。
method 表达式是指在调用 method 的时候,必须要提供接收者,把方法的接收者替换成函数的第一个形参,使它可以像函数一样调用。通常用于需要一个值代表属于同一个类型的多个 method 中的一个,method 变量可以帮助你调用这个值所对应的方法来处理不同的接收者。
- 计算机程序的思维逻辑 (8) - char的真正含义
- 搭建Docker私有仓库--自签名方式
- 详解JavaScript闭包
- Python多进程抓取全国邮政编码和长途区号
- [个人翻译]Redis 集群教程(下)
- [个人翻译]Redis 集群教程(中)
- 自学Apache Spark博客(节选)
- scrapy爬取免费代理IP存储到数据库构建自有IP池
- 每天一个Linux命令:netstat
- Hadoop - MapReduce
- 进击的爬虫:用Python搭建匿名代理池
- 计算机程序的思维逻辑 (5) - 小数计算为什么会出错?
- QQ空间爬虫最新分享,一天 400 万条数据
- 计算机程序的思维逻辑 (4) - 整数的二进制表示与位运算
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 带分数 第四届蓝桥杯省赛C++B组
- codeforce1178B (DP)
- String Modification (CodeCraft-20 (Div. 2))
- codeforces 107A(dfs)
- codeforces 698A(暴力)
- 机器人跳跃问题 (二分)
- codeforces 1066B(贪心)
- 机器学习模型评估指标总结!
- 地宫取宝 (第五届蓝桥杯省赛C++A/B组)
- codeforce 650A (数学)
- POJ3279 (二进制枚举)
- codeforces 1312C(思维)
- codeforces1369C(贪心)
- 新人赛《金融风控贷款违约》避坑指南!
- codeforces 911C (找规律)