写在前面

  • 嗯,学习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语言实战之函数与方法相关推荐

  1. 自定义strcpy函数c语言,c语言编写strcpy函数的方法

    c语言编写strcpy函数的方法 1.搭建基本的C语言程序框架,注意添加#include头文件 2.定义两个字符数组 3.strcpy函数原型:char *strcpy(char *dest, con ...

  2. 3.1 Go语言中的函数与方法

    函数定义语法 与大部分语言一致,Go语言中的函数定义与其他语言基本一致 func function_name(Parameter-list) {// function body... }func fu ...

  3. c#语言怎么定义函数,C#方法方法用法 _C#语言-w3school教程

    C#语言 的 C#方法 C#中的方法是一组执行任务的语句. 每个 C# 程序至少有一个类包含一个名称为Main()的方法. 要使用方法,需要: 定义方法 调用方法 C# 中定义方法 当要定义一个方法时 ...

  4. C语言实现RAND函数的方法

    C语言使用rand()%一个值就可以实现生成一个伪随机数供我们使用,那么rand函数是如何实现的呢?我们自己可不可以编辑出来?其实是可以的,rand作为伪随机数发生器产生的是一个伪随机数,一般的用途能 ...

  5. c语言函数的使用步骤,c语言打开文件函数使用方法

    ANSI C规定文件打开用函数fopen,关闭为fclose. 1.调用方式通常为: FILE *fp; fp=fopen(文件名, 打开方式); 2.参数说明: 文件名: 形如"myfil ...

  6. Go语言教程第三集 集合、函数和方法

    04 集合类型:如何正确使用 array.lice 和 map? 上节课的思考题是练习使用 for 循环中的 continue,通过上节课的学习,你已经了解 continue 是跳出本次循环的意思,现 ...

  7. C语言实战——生产者消费者问题

    C语言实战--生产者消费者问题 方法摘要 生产者消费者共享缓冲区,生产者向缓冲区中放数据,消费者从缓冲取中取数据,当缓冲区中被放满时,生产者进程就必须进入挂起状态,直到消费者从缓冲中取走数据时,生产者 ...

  8. c语言实验报告函数和宏定义,第六章 实验报告(函数与宏定义)

    ##C程序设计实验报告 ###一.实验项目: 1.编写由三角形三边求面积的函数 2.编写求N阶乘的函数 3.求两个整数的最大公约数 4.打印输出三角形 5.求500以内的所有亲密数对 ##姓名:戴求  ...

  9. R语言使用integrate函数进行函数积分计算实战

    R语言使用integrate函数进行函数积分计算实战 目录 R语言使用integrate函数进行函数积分计算实战 #自定义函数 #积分操作

  10. R语言使用tryCatch函数调试R代码实战:tryCatch函数运行正常R代码、tryCatch函数运行有错误(error)的R代码示例/tryCatch函数运行有警告(warning)的R代码示例

    R语言使用tryCatch函数调试R代码实战:tryCatch函数运行正常R代码.tryCatch函数运行有错误(error)的R代码示例/tryCatch函数运行有警告(warning)的R代码示例 ...

最新文章

  1. 切割图形_3D打印、激光切割、图形化编程,六一科普活动喊你来报名啦!
  2. 160个Crackme030之一元一次方程
  3. 微信小程序 html modal,微信小程序参考微信设计规范做的modal模态框
  4. 牛客13592 武藏牌牛奶促销
  5. QT学习笔记(六):Qt5主窗口框架示例
  6. 目标检测之YOLO V2 V3
  7. android分享图片功能实现原理,Android:简单实现并理解图片三级缓存
  8. 【leetcode】Maximum Subarray
  9. Spring 注解 @Controller,@Service,@Repository,@Component,重定向 与 服务端跳转
  10. You need to use a Theme.AppCompat theme (or descendant) with this activity
  11. asp.net网页版斗地主 已提供下载(开源) 测试版
  12. 海量Oracle学习视频分享
  13. Latex设置中文标题样式
  14. gprs模块与服务器通信协议,gprs模块与服务器通信原理分析
  15. 洛谷 P2119 魔法阵
  16. less日常容易忘记的知识记录
  17. 回归分析中的p值和R方哪个更重要?
  18. 【重磅盘点】62种PCB板不良实例的原因分析及规避措施!必收藏干货!
  19. CF 1646D Weight the Tree 树形dp
  20. 智慧渣土运输管控系统

热门文章

  1. 将超星PDG文件转换成PDF文件的方法
  2. oracle数据库的监听配置
  3. 【真题21套】计算机二级公共基础知识选择题真题【含解析】
  4. UltraISO9.3.0.2610中文绿色注册版
  5. python123平台登陆页_从头搭建一个flask鉴权系统之登陆
  6. div 和table
  7. 热血江湖游戏窗口化的方法
  8. JPYXGSIT故障解决方案
  9. 蓝牙条码扫描枪如何选购
  10. 微pe工具箱 系统安装教程_【微pe安装系统教程】微pe安装系统教程win7_微pe装系统教程...