GO语言实战之函数与方法
写在前面
- 嗯,学习
GO
,所以有了这篇文章 - 博文内容为
《GO语言实战》
读书笔记之一 - 主要涉及知识
- GO函数及其他语言对比
- GO用户定义类型(结构体)
- Go方法
傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波
函数
对于这个概念小伙伴一定不陌生,常用的脚本语言中一般都会用,通过函数来整合一些逻辑上耦合性较强的代码块,从而提高代码的可读性,可复用性。
GO语言中的函数语法格式和其他语言略有不同,函数可以先使用后定义,同时go支持闭包,拆包,异常信息返回等
语法格式
func funcName(param paramType)(returnVal1 returnType, err error){// do something
}
demo
package mainimport ("fmt""time"
)func main() {nowTime := time.Now()fmt.Println(nowTime.Format("2006-01-02 15:04:05"))// 拆包i, j := func_demo()//调用有参函数func_demos("你好,世界!")fmt.Println(i, j)// 匿名函数get_func_demo := func(x int) int {return x}fmt.Println(get_func_demo(3))// 闭包f := get_func_()fmt.Println(f())
}
// 拆包
func func_demo() (int, int) {fmt.Println("你好,世界!")return 1, 2
}
// 接收参数
func func_demos(mes string) {fmt.Println(mes)
}
// 闭包
func get_func_() (func() int){i := 1return func() (int) {i+=1return i}
}
============
2022-04-14 10:01:03
你好,世界!
你好,世界!
1 2
3
2
其他的脚本语言对比
对于Shell
脚本来说,shell脚本中的函数只能先定义后使用,函数可以看做是一个微小版的shell脚本,功能语法相对简单
#!/bin/bash# 带关键字定义
function f(){echo $(date)
}
f# 直接函数名的方式定义
func_name(){echo "Hello,Word!"
}
func_name# 接受入参
func_names(){echo "${0}"echo "${1}"
}
func_names 5# 返回数组
func_array(){my_array=("liruilong" 1 2 3)echo ${my_array[*]}
}
retuens=($(func_array))
echo "${retuens[*]}"# 返回信号
func_return(){return 1
}
func_return===========================
2022年 04月 14日 星期四 10:36:20 CST
Hello,Word!
fun.sh
5
liruilong 1 2 3
对于Python
来讲,函数也必须先定义后使用。python的函数语法要多一点,支持可变参数,关键字参数,缺省参数,同时支持拆包,闭包等
#!/usr/bin/python3
# -*- coding: UTF-8 -*-def func_demo():print("Hello,Word")
func_demo()def func_param(a,b,c=","):print(a,c,b)
func_param("Hello","Word")
func_param(b="Word",a="Hello")def func_return():return 2
print(func_return())def func_arges(a,*arges):for i in arges:print(i)
func_arges(1,2,3)
func_arges(1)def func_aeges_(**arges):print(arges)
func_aeges_(name='liruilong', age=18, id=110)def return_num():return 100, 200
num1, num2 = return_num()
==========================
Hello,Word
Hello , Word
Hello , Word
2
2
3
{'name': 'liruilong', 'age': 18, 'id': 110}
关于函数介绍到这里,来看看方法,GO语言中方法实际上也是函数,只是在声明时,在关键字func
和方法名
之间增加了一个参数
在面向对象里,方法是类行为和对象行为的体现(类方法和实例方法),GO不是面向对象类型的语言,但是Go方法和java中的方法类似,同样不能单一存在,必须要绑定。
Java中的方法
/*** @Classname Function* @Description TODO* @Date 2022/4/14 23:09* @Created LiRuilong*/
public class Function {String str;// 对象方法public String getStr(){return str;}// 类方法public static Function build(){return new Function();}public static void main(String[] args) {System.out.println("Hello,Word!");}
}
java中方法必定是和类
或者对象
绑定的,和类绑定的方法被称为静态方法,和对象绑定的为实例方法。GO中的方法必须要和接收者绑定,那GO
中的所谓的接收者又是什么?,即用户定义的类型,听着有些别扭,类比C
中我们常讲的结构体
用户定义的类型(结构体)
Go 语言允许用户定义类型(结构体)
。当用户声明一个新类型时,这个声明就给编译器提供了一个框架,告知必要的内存大小
和表示信息
Go 语言里声明用户定义的类型有两种方法。最常用的方法是使用关键字struct
,它可以让用户创建一个结构类型
。
结构里每个字段
都会用一个已知类型声明
。这个已知类型可以是内置类型
,也可以是其他用户定义的类型
。
- 声明一个结构类型
type user struct {name stringemail string
}
- 使用结构类型声明变量,并初始化为其零值
var bill user
当声明变量时,这个变量对应的值总是会被初始化
。这个值要么用指定的值初始化
,要么用零值
(即变量类型的默认值
)做初始化
- 对数值类型来说,
零值是 0
; - 对字符串来说,零值是
空字符串
; - 对布尔类型,零值是
false
。
:=
:一个短变量声明操作符在一次操作中完成两件事情:声明一个变量,并初始化
- 使用
结构字面量
来声明一个结构类型的变量
lisa := user{name: "liruilong",email: "liruilong@qq.com"
}
- 使用结构字面量创建结构类型的值
user{name: "liruilong",email: "liruilong@qq.com"
}
- 不使用字段名,创建结构类型的值,这种形式下,值的顺序很重要,必须要和结构声明中字段的顺序一致。
user{"Bill", "bill@email.com"}
当声明结构类型时,字段的类型并不限制在内置类型,也可以使用其他用户定义的类型
- 使用其他结构类型声明字段
type admin struct{liruilong user,leve string
}
fred := admin{liruilong: user{"Bill", "bill@email.com"},level: "super",
}
另一种声明用户定义的类型的方法是,基于一个已有的类型,将其作为新类型的类型说明
。
基于 int64 声明一个新类型
type Duration int64
Duration
是一种描述时间间隔的类型,单位是纳秒(ns)。这个类型使用内置的 int64 类型作为其表示
我们把 int64 类型叫作 Duration 的基础类型,Go 并不认为 Duration 和 int64 是同一种类型。这两个类型是完全不同的有区别的,这里和有些面向对象的语言有很大的区别。
- 给不同类型的变量赋值会产生编译错误
package mainimport ("fmt"
)
type Duration int64func main() {var dur Duration//正确写法 ur = Duration(1000) dur = int64(1000)fmt.Println(dur)
}============
[Running] go run "d:\GolandProjects\code-master\demo\hello.go"
# command-line-arguments
demo\hello.go:10:6: cannot use int64(1000) (type int64) as type Duration in assignment[Done] exited with code=2 in 0.705 seconds
OK,了解了GO中的结构体,我们来看看方法
方法
在GO
中,通过方法
能给用户定义的类型
也就是俗称的结构体
添加新的行为。声明时,func
和方法名
之间增加了一个结构体参数
我们把关键字func
和函数名之间的参数被称作接收者
,将函数
与接收者
的类型绑在一起。如果一个函数有接收者,这个函数就被称为方法。
Go 语言里有两种类型的接收者:值接收者
,指针接收者
。
使用值接收者声明一个方法
// notify 使用值接收者实现了一个方法
func (u user) notify() {fmt.Printf("Sending User Email To %s<%s>\n",u.name,u.email)
}
如果使用值接收者声明方法
,调用时会使用这个值的一个副本来执行
。使用 bill
的值作为接收者进行调用,方法 notify 会接收到 bill 的值的一个副本。
// user 类型的值可以用来调用使用值接收者声明的方法bill := user{"Bill", "bill@email.com"}bill.notify()
也可以使用指针来调用使用值接收者声明的方法
,使用指向 user 类型值的指针来调用 notify 方法
// 指向 user 类型值的指针也可以用来调用使用值接收者声明的方法lisa := &user{"Lisa", "lisa@email.com"}lisa.notify() //(*lisa).notify()
指针被解引用为值,不管是变量调用还是指针调用,notify 操作的都是一个副本。
使用指针接收者声明一个方法
// changeEmail 使用指针接收者实现了一个方法
func (u *user) changeEmail(email string) {u.email = email
}
使用指针接收者声明。这个接收者的类型是指向 user 类型值的指针,而不是 user 类型的值。当调用使用指针接收者声明的方法时,这个方法会共享调用方法时接收者所指向的值
这一点和使用值接收有很大的区别,某种意义上讲,使用值接收
一般用于消费,使用指针接收
,一般用于生产加工修饰。
lisa := &user{"Lisa", "lisa@email.com"}
// 指向 user 类型值的指针可以用来调用使用指针接收者声明的方法
lisa.changeEmail("lisa@newdomain.com")
lisa.notify()
值接收者使用值的副本来调用方法,而指针接受者使用实际值来调用方法。
bill := user{"Bill", "bill@email.com"}
// user 类型的值可以用来调用使用指针接收者声明的方法
bill.changeEmail("bill@newdomain.com")
bill.notify() //(&bill).changeEmail ("bill@newdomain.com")
Go语言既允许使用值,也允许使用指针来调用方法,不必严格符合接收者的类型
// 声明 并使用方法
package mainimport ("fmt"
)// user 在程序里定义一个用户类型
type user struct {name stringemail string
}// notify 使用值接收者实现了一个方法,一般用于消费对象
func (u user) notify() {fmt.Printf("Sending User Email To %s<%s>\n",u.name,u.email)
}// changeEmail 使用指针接收者实现了一个方法,一般用于生产加工对象
func (u *user) changeEmail(email string) {u.email = email
}// main 是应用程序的入口
func main() {// user 类型的值可以用来调用使用值接收者声明的方法bill := user{"Bill", "bill@email.com"}bill.notify()// 指向 user 类型值的指针也可以用来调用使用值接收者声明的方法lisa := &user{"Lisa", "lisa@email.com"}lisa.notify()// user 类型的值可以用来调用使用指针接收者声明的方法bill.changeEmail("bill@newdomain.com")bill.notify()// 指向 user 类型值的指针可以用来调用使用指针接收者声明的方法lisa.changeEmail("lisa@newdomain.com")lisa.notify()
}
================
[Running] go run "d:\GolandProjects\code-master\chapter5\listing11\tempCodeRunnerFile.go"
Sending User Email To Bill<bill@email.com>
Sending User Email To Lisa<lisa@email.com>
Sending User Email To Bill<bill@newdomain.com>
Sending User Email To Lisa<lisa@newdomain.com>[Done] exited with code=0 in 2.288 seconds
GO语言实战之函数与方法相关推荐
- 自定义strcpy函数c语言,c语言编写strcpy函数的方法
c语言编写strcpy函数的方法 1.搭建基本的C语言程序框架,注意添加#include头文件 2.定义两个字符数组 3.strcpy函数原型:char *strcpy(char *dest, con ...
- 3.1 Go语言中的函数与方法
函数定义语法 与大部分语言一致,Go语言中的函数定义与其他语言基本一致 func function_name(Parameter-list) {// function body... }func fu ...
- c#语言怎么定义函数,C#方法方法用法 _C#语言-w3school教程
C#语言 的 C#方法 C#中的方法是一组执行任务的语句. 每个 C# 程序至少有一个类包含一个名称为Main()的方法. 要使用方法,需要: 定义方法 调用方法 C# 中定义方法 当要定义一个方法时 ...
- C语言实现RAND函数的方法
C语言使用rand()%一个值就可以实现生成一个伪随机数供我们使用,那么rand函数是如何实现的呢?我们自己可不可以编辑出来?其实是可以的,rand作为伪随机数发生器产生的是一个伪随机数,一般的用途能 ...
- c语言函数的使用步骤,c语言打开文件函数使用方法
ANSI C规定文件打开用函数fopen,关闭为fclose. 1.调用方式通常为: FILE *fp; fp=fopen(文件名, 打开方式); 2.参数说明: 文件名: 形如"myfil ...
- Go语言教程第三集 集合、函数和方法
04 集合类型:如何正确使用 array.lice 和 map? 上节课的思考题是练习使用 for 循环中的 continue,通过上节课的学习,你已经了解 continue 是跳出本次循环的意思,现 ...
- C语言实战——生产者消费者问题
C语言实战--生产者消费者问题 方法摘要 生产者消费者共享缓冲区,生产者向缓冲区中放数据,消费者从缓冲取中取数据,当缓冲区中被放满时,生产者进程就必须进入挂起状态,直到消费者从缓冲中取走数据时,生产者 ...
- c语言实验报告函数和宏定义,第六章 实验报告(函数与宏定义)
##C程序设计实验报告 ###一.实验项目: 1.编写由三角形三边求面积的函数 2.编写求N阶乘的函数 3.求两个整数的最大公约数 4.打印输出三角形 5.求500以内的所有亲密数对 ##姓名:戴求 ...
- R语言使用integrate函数进行函数积分计算实战
R语言使用integrate函数进行函数积分计算实战 目录 R语言使用integrate函数进行函数积分计算实战 #自定义函数 #积分操作
- R语言使用tryCatch函数调试R代码实战:tryCatch函数运行正常R代码、tryCatch函数运行有错误(error)的R代码示例/tryCatch函数运行有警告(warning)的R代码示例
R语言使用tryCatch函数调试R代码实战:tryCatch函数运行正常R代码.tryCatch函数运行有错误(error)的R代码示例/tryCatch函数运行有警告(warning)的R代码示例 ...
最新文章
- 切割图形_3D打印、激光切割、图形化编程,六一科普活动喊你来报名啦!
- 160个Crackme030之一元一次方程
- 微信小程序 html modal,微信小程序参考微信设计规范做的modal模态框
- 牛客13592 武藏牌牛奶促销
- QT学习笔记(六):Qt5主窗口框架示例
- 目标检测之YOLO V2 V3
- android分享图片功能实现原理,Android:简单实现并理解图片三级缓存
- 【leetcode】Maximum Subarray
- Spring 注解 @Controller,@Service,@Repository,@Component,重定向 与 服务端跳转
- You need to use a Theme.AppCompat theme (or descendant) with this activity
- asp.net网页版斗地主 已提供下载(开源) 测试版
- 海量Oracle学习视频分享
- Latex设置中文标题样式
- gprs模块与服务器通信协议,gprs模块与服务器通信原理分析
- 洛谷 P2119 魔法阵
- less日常容易忘记的知识记录
- 回归分析中的p值和R方哪个更重要?
- 【重磅盘点】62种PCB板不良实例的原因分析及规避措施!必收藏干货!
- CF 1646D Weight the Tree 树形dp
- 智慧渣土运输管控系统