100天精通Golang(基础入门篇)——第19天:深入剖析Go语言中方法(Method)的妙用与实践
🌷🍁 博主猫头虎 带您 Go to Golang Language.✨✨🍁
🦄 博客首页——猫头虎的博客🎐
🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺
🌊 《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐
🌊 《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大小厂~💐
🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥
100天精通Golang(基础入门篇)
- 方法
- 摘要 📝
- 引言 🎙️
- 导语 🗺️
- 1.1 什么是方法
- 1.2 方法的语法
- 1.3 方法和函数
- 1.4 变量作用域
- 1.5 method继承
- 1.6 method重写
- 1.7 接口与方法
- 1.8 方法的签名
- 1.9 方法值和方法表达式
- 方法值
- 方法表达式
- 1.10 方法的可见性
- 总结🌟
- 参考资料
- 结语
方法
深入剖析Go语言:第19天专注方法(Method)的妙用与实践
摘要 📝
掌握Go语言的方法(Method)🛠️不仅能让你的代码更加有序✅,也能实现更多功能🚀和更高的可维护性🔧。本篇博客是我们"100天精通Golang"系列📚的第19篇,将深入解释Go中方法的语法📖、用法🤔、作用范围🌐以及与函数的区别🔄等。
引言 🎙️
你好,亲爱的读者👋,我是猫头虎博主😺🐅!Go语言因其简洁🗂️、高效⚡而日益受到开发者的喜爱💖。然而,要想充分利用Go语言的强大功能💪,理解其方法(Method)的概念🧠是非常必要的。在本篇博客中,我们将一同探讨Go语言中的方法概念🕵️♀️,看看它是如何使我们的编程生活变得更美好😊。
导语 🗺️
本篇博文将覆盖以下几个方面📋:
1️⃣ 方法的基本语法和定义方式📐
2️⃣ 值接收者和指针接收者的区别🔍
3️⃣ 方法与函数的对比📊
4️⃣ 局部变量和全局变量在方法中的应用📍
5️⃣ 方法的继承与重写🔄
无论你是Go语言的新手👶还是有经验的开发者👨💻,我相信这篇文章都能给你带来一些新的见解🌟。
这样的格式更加吸引人,并且能在视觉上快速传达重要信息。希望这能帮助你!😊
1.1 什么是方法
Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集
方法只是一个函数,它带有一个特殊的接收器类型,它是在func关键字和方法名之间编写的。接收器可以是struct类型或非struct类型。接收方可以在方法内部访问。
方法能给用户自定义的类型添加新的行为。它和函数的区别在于方法有一个接收者,给一个函数添加一个接收者,那么它就变成了方法。接收者可以是值接收者,也可以是指针接收者。
在调用方法的时候,值类型既可以调用值接收者的方法,也可以调用指针接收者的方法;指针类型既可以调用指针接收者的方法,也可以调用值接收者的方法。
也就是说,不管方法的接收者是什么类型,该类型的值和指针都可以调用,不必严格符合接收者的类型。
1.2 方法的语法
定义方法的语法
func (t Type) methodName(parameter list)(return list) {}
func funcName(parameter list)(return list){}
实例代码:
package mainimport ( "fmt"
)type Employee struct { name stringsalary intcurrency string
}/*displaySalary() method has Employee as the receiver type
*/
func (e Employee) displaySalary() { fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}func main() { emp1 := Employee {name: "Sam Adolf",salary: 5000,currency: "$",}emp1.displaySalary() //Calling displaySalary() method of Employee type
}
可以定义相同的方法名
示例代码:
package mainimport ("fmt""math"
)type Rectangle struct {width, height float64
}
type Circle struct {radius float64
}func (r Rectangle) area() float64 {return r.width * r.height
}
//该 method 属于 Circle 类型对象中的方法
func (c Circle) area() float64 {return c.radius * c.radius * math.Pi
}
func main() {r1 := Rectangle{12, 2}r2 := Rectangle{9, 4}c1 := Circle{10}c2 := Circle{25}fmt.Println("Area of r1 is: ", r1.area())fmt.Println("Area of r2 is: ", r2.area())fmt.Println("Area of c1 is: ", c1.area())fmt.Println("Area of c2 is: ", c2.area())
}
运行结果
Area of r1 is: 24
Area of r2 is: 36
Area of c1 is: 314.1592653589793
Area of c2 is: 1963.4954084936207
- 虽然method的名字一模一样,但是如果接收者不一样,那么method就不一样
- method里面可以访问接收者的字段
- 调用method通过.访问,就像struct里面访问字段一样
1.3 方法和函数
既然我们已经有了函数,为什么还要使用方法?
示例代码:
package mainimport ( "fmt"
)type Employee struct { name stringsalary intcurrency string
}/*displaySalary() method converted to function with Employee as parameter
*/
func displaySalary(e Employee) { fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}func main() { emp1 := Employee{name: "Sam Adolf",salary: 5000,currency: "$",}displaySalary(emp1)
}
在上面的程序中,displaySalary方法被转换为一个函数,而Employee struct作为参数传递给它。这个程序也产生了相同的输出:Salary of Sam Adolf is $5000.。
为什么我们可以用函数来写相同的程序呢?有以下几个原因
- Go不是一种纯粹面向对象的编程语言,它不支持类。因此,类型的方法是一种实现类似于类的行为的方法。
- 相同名称的方法可以在不同的类型上定义,而具有相同名称的函数是不允许的。假设我们有一个正方形和圆形的结构。可以在正方形和圆形上定义一个名为Area的方法。这是在下面的程序中完成的。
1.4 变量作用域
作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
Go 语言中变量可以在三个地方声明:
- 函数内定义的变量称为局部变量
- 函数外定义的变量称为全局变量
- 函数定义中的变量称为形式参数
局部变量
在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。
全局变量
在函数体外声明的变量称之为全局变量,首字母大写全局变量可以在整个包甚至外部包(被导出后)使用。
package mainimport "fmt"/* 声明全局变量 */
var g intfunc main() {/* 声明局部变量 */var a, b int/* 初始化参数 */a = 10b = 20g = a + bfmt.Printf("结果: a = %d, b = %d and g = %d\n", a, b, g)
}
结果
结果: a = 10, b = 20 and g = 30
形式参数
形式参数会作为函数的局部变量来使用
指针作为接收者
若不是以指针作为接收者,实际只是获取了一个copy,而不能真正改变接收者的中的数据
func (b *Box) SetColor(c Color) {b.color = c
}
示例代码
package mainimport ("fmt"
)type Rectangle struct {width, height int
}func (r *Rectangle) setVal() {r.height = 20
}func main() {p := Rectangle{1, 2}s := pp.setVal()fmt.Println(p.height, s.height)
}
结果
20 2
如果没有那个*,则值就是2 2
1.5 method继承
method是可以继承的,如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method
package mainimport "fmt"type Human struct {name stringage intphone string
}
type Student struct {Human //匿名字段school string
}
type Employee struct {Human //匿名字段company string
}func (h *Human) SayHi() {fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}mark.SayHi()sam.SayHi()
}
运行结果:
Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam you can call me on 111-888-XXXX
1.6 method重写
package mainimport "fmt"type Human struct {name stringage intphone string
}
type Student struct {Human //匿名字段school string
}
type Employee struct {Human //匿名字段company string
}//Human定义method
func (h *Human) SayHi() {fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}//Employee的method重写Human的method
func (e *Employee) SayHi() {fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,e.company, e.phone) //Yes you can split into 2 lines here.
}
func main() {mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}mark.SayHi()sam.SayHi()
}
运行结果:
Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam, I work at Golang Inc. Call me on 111-888-XXXX
- 方法是可以继承和重写的
- 存在继承关系时,按照就近原则,进行调用
1.7 接口与方法
在 Go 语言中,接口定义了一组方法,但这些方法不包含实现代码。它们没有被绑定到特定的类型。接口的方法可以通过任何类型来实现,这样该类型就满足了接口。
type Sayer interface {Say() string
}type Dog struct {
}func (d Dog) Say() string {return "Woof!"
}type Cat struct {
}func (c Cat) Say() string {return "Meow!"
}func AnimalTalk(s Sayer) {fmt.Println(s.Say())
}func main() {var d Sayer = Dog{}var c Sayer = Cat{}AnimalTalk(d)AnimalTalk(c)
}
在这个例子里,Sayer
接口包含了一个 Say
方法。我们定义了两个结构体类型 Dog
和 Cat
,然后使它们都满足 Sayer
接口。最后,在 AnimalTalk
函数中使用接口作为参数,实现了多态。
1.8 方法的签名
每个方法都有一个方法签名,这告诉我们方法接受哪种类型的接收者。这非常重要,因为这决定了哪些方法属于接口类型,或者更通用地说,它决定了一组方法(以及它们的签名)如何形成一个接口。
type Geometry interface {Area() float64Perimeter() float64
}type Square struct {side float64
}func (s Square) Area() float64 {return s.side * s.side
}func (s Square) Perimeter() float64 {return 4 * s.side
}
在这里,Geometry
接口包含 Area
和 Perimeter
方法,这两个方法都没有参数并返回一个浮点数。因此,任何具有这两个方法的类型都满足 Geometry
接口。
1.9 方法值和方法表达式
在 Go 中,方法不仅可以作为接收者类型的一部分来调用,还可以作为独立的值和表达式。
方法值
当你保存方法作为值时,接收者也会被保存。
type Greeter struct {Name string
}func (g Greeter) Greet() {fmt.Println("Hello", g.Name)
}func main() {greet := Greeter{Name: "John"}.Greetgreet()
}
方法表达式
方法表达式返回一个函数,该函数接受一个接收者和原方法的其他参数。
type Adder struct {Base int
}func (a Adder) Add(x int) int {return a.Base + x
}func main() {add := Adder{Base: 2}.Addfmt.Println(add(3)) // Output: 5
}
1.10 方法的可见性
和字段或函数一样,如果方法的第一个字母是大写的,那么这个方法可以被这个包以外的代码访问。这是 Go 的导出规则。
package geometrytype Rectangle struct {Length, Width float64
}func (r Rectangle) Area() float64 {return r.Length * r.Width
}func (r Rectangle) perimeter() float64 {return 2 * (r.Length + r.Width)
}
在上面的例子中,Area
方法是导出的,因为它以大写字母开头,而 perimeter
则不是因为它以小写字母开头。
通过这些主题的讨论,希望能够增加你对 Go 语言中方法的深入理解。接下来,我们将探讨更高级的主题,以帮助你成为一名更出色的 Go 程序员。敬请期待!
总结🌟
掌握Go语言中的方法(Method)不仅是基础学习的重要一环,而且对于高级编程和实际应用也有着至关重要的作用。通过这篇文章,我希望你能对Go语言的方法有一个更全面和深入的理解,从而能够更加灵活和高效地使用这一强大的编程语言。
在这篇博客中,我详细讲解了Go语言中“方法”(Method)的重要性和应用。该博客是"100天精通Golang"系列的第19篇文章。主要内容围绕方法在Go语言中的基础语法、与函数的区别,以及方法的用法和应用范围进行了全面而深入的介绍。
1️⃣ 基础语法和定义方式: 方法是Go语言编程中的一个关键概念,理解它有助于写出更有序和可维护的代码。
2️⃣ 值接收者和指针接收者: 文章解释了这两种接收者的区别和各自适用的场合。
3️⃣ 方法与函数的对比: 了解这两者的不同能帮助你更准确地应用它们。
4️⃣ 局部变量和全局变量的应用: 在方法中,如何使用这两种变量也是一个需要注意的点。
5️⃣ 方法的继承与重写: 在面向对象编程中,了解如何继承和重写方法是非常重要的。
无论你是Go语言初学者还是经验丰富的开发者,这篇文章都提供了有价值的信息和见解。
通过这篇博客,你可以更全面地理解Go语言中的“方法”,从而更有效地使用Go进行编程。
参考资料
- “The Go Programming Language” by Alan A. A. Donovan & Brian W. Kernighan
- Go官方文档:Methods - The Go Programming Language
- “Go语言高级编程” by Chai2010
- Go by Example: Methods
- Understanding Go Interfaces
感谢大家的阅读,如果你觉得这篇文章有用,不妨分享给你的朋友和同事,也别忘了关注猫头虎博主的更多精彩内容!我们下篇文章见!
结语
通过今天的学习,您已经踏上了Golang的学习之旅。在未来的日子里,您将探索Golang的各个方面,从基础概念到高级技巧,从实际应用到性能优化。
学习一门编程语言是一个持续的过程,每一天都是您向Golang的精通迈进的重要一步。我鼓励您坚持每天学习,保持热情和好奇心,解决挑战并享受成功的喜悦。
在您的学习旅程中,不要忘记参与社区和与其他Golang开发者交流。分享您的见解和经验,向他人学习,并在开源项目或实际应用中展示您的技能。
如果您在学习过程中遇到困难或有任何问题,不要犹豫向社区和专家寻求帮助。持续学习,勇敢探索,您将在Golang领域取得令人瞩目的成就。
最后,感谢您的阅读和支持!祝愿您在未来的每一天中都能够成为一名精通Golang的开发者!
期待听到您在学习过程中的进展和成就。如果您需要进一步的帮助,请随时告诉我。祝您在学习Golang的旅程中取得巨大成功!
点击
下方名片
,加入IT技术核心学习团队。一起探索科技的未来,共同成长。
如果您在学习过程中有任何疑惑,请点击下方名片,带您一对一快速入门 Go语言 的世界 ~
相关文章:

100天精通Golang(基础入门篇)——第19天:深入剖析Go语言中方法(Method)的妙用与实践
🌷🍁 博主猫头虎 带您 Go to Golang Language.✨✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~…...

【人工智能】—_不确定性、先验概率_后验概率、概率密度、贝叶斯法则、朴素贝叶斯_、最大似然估计
【人工智能】— 不确定性、先验概率/后验概率、概率密度、贝叶斯法则、朴素贝叶斯 文章目录 【人工智能】— 不确定性、先验概率/后验概率、概率密度、贝叶斯法则、朴素贝叶斯不确定性不确定性与理性决策基本概率符号先验概率(无条件概率)/后验概率(条件概率)随机变量概率密度联…...

postgresql-字符函数
postgresql-字符函数 字符串连接字符与编码字符串长度大小写转换子串查找与替换截断与填充字符串格式化MD5 值字符串拆分字符串反转 字符串连接 concat(str, …)函数用于连接字符串,并且忽略其中的 NULL 参数;concat_ws(sep, str, …) 函数使用指定分隔…...

VUE笔记(五)网络通信
一、axios的简介 1、什么是axios 文档:Axios 中文文档 | Axios 中文网 | Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js 概念:axios是一个基于Promise的网络请求库,可以用于浏览器和node.js 特点ÿ…...

微信小程序修改数据,input不能实时回显
场景: 填写发票抬头,填写抬头公司时候,会根据用户输入的内容实时获取相关的公司信息,用户选择搜索出来的公司,这时候 setData,但是数据并没有回显,而是需要再需要点一下屏幕。 解决方案: 原来…...

GitHub Copilot三连更:能在代码行里直接提问,上下文范围扩展到终端
量子位 | 公众号 QbitAI 就在昨晚,GitHub Copilot迎来了一波不小的更新。 包括: 全新交互体验——代码行中直接召唤聊天功能,不用切界面,主打一个专注; 改善斜杠命令,一键删除,主打快捷操作、…...

双亲委派机制
双亲委派机制流程 当Application ClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器Extension ClassLoader去完成。 当Extension ClassLoader收到一个类加载请求时,他首先也不会自己去尝试…...

美团北极星榜单,服务零售的医美新样本
事实证明,任何时候,人们对美的追求都是刚需,只是有时候被压抑了。 德勤中国的《中国医美行业2023年度洞悉报告》(以下简称“报告”)显示,中国医美市场规模预计在2023年超过2000亿元,实现20%增速…...

geant4 常用代码
1 获取特特定能量范围的特定粒子 E:\examples_understanding\geant4-v11.0.0_note\examples\extended\runAndEvent\RE02 //-- Particle with kinetic energy filter.G4SDParticleWithEnergyFilter* pkinEFilter new G4SDParticleWithEnergyFilter(fltName"gammaE filter&…...

重要通知!eBay将升级买家满意度考核,如何让你的店铺脱颖而出?
8月份,eBay发布了重要通知,为促进跨境卖家积极提升买家体验,升级了针对卖家的买家满意度考核。其中,产品质量是买家满意度考核的核心,是中国卖家急需提升的重中之重,也是eBay考核的重点。 eBay将着眼于产品…...

PHP中pack、unpack的用法
pack string pack ( string $format [, mixed $args [, mixed $... ]] ) 该函数用来将对应的参数($args)打包成二进制字符串。 其中第一个参数$format,有如下选项: a 以NUL字节填充字符串空白 A 以SPACE(空格)填充字符串 h 十六进制字符串&…...

KUKA机器人零点标定的具体方法
KUKA机器人零点标定的具体方法 在进行机器人校正时,先将各轴置于一个定义好的机械位置,即所谓的机械零点。这个机械零点位置表明了同轴的驱动角度之间的对应关系,它用一个测量刻槽表示。 为了精确地确定机器人某根轴的机械零点位置,一般应先找到其预校正位置,然后去掉测量…...

基于SpringBoot+Vue的旅游系统
摘 要 随着旅游业的发展,越来越多的人选择旅游作为自己的出行方式。在旅游规划过程中,旅游景点选择是至关重要的环节。本文提出了一种基于协同过滤推荐算法的旅游平台系统。该系统采用前后端分离的设计,主要使用了SpringBoot、Vue等技术&…...

leetcode算法题--复杂链表的复制
原题链接:https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/description/?envTypestudy-plan-v2&envIdcoding-interviews 感觉一开始想到的办法还是比较笨 /*** Definition for a Node.* type Node struct {* Val int* Next *Node* …...

C++面试题(叁)---操作系统篇
目录 操作系统篇 1 Linux中查看进程运行状态的指令、查看内存使用情况的指令、 tar解压文件的参数。 2 文件权限怎么修改 3 说说常用的Linux命令 4 说说如何以root权限运行某个程序。 5 说说软链接和硬链接的区别。 6 说说静态库和动态库怎么制作及如何使用,区…...

算法笔记:KD树
1 引入原因 K近邻算法需要在整个数据集中搜索和测试数据x最近的k个点,如果一一计算,然后再排序,开销过大 引入KD树的作用就是对KNN搜索和排序的耗时进行改进 2 KD树 2.1 主体思路 以空间换时间,利用训练样本集中的样本点&…...

plumelog介绍与应用-一个简单易用的java分布式日志系统
官方文档:http://www.plumelog.com/zh-cn/docs/FASTSTART.html 简介 无代码入侵的分布式日志系统,基于log4j、log4j2、logback搜集日志,设置链路ID,方便查询关联日志基于elasticsearch作为查询引擎高吞吐,查询效率高全…...

百度网盘删除“我的应用数据”文件夹
百度网盘删除“我的应用数据”文件夹电脑端方法-2023.2.27成功 - 哔哩哔哩 (bilibili.com) 百度网盘怎样删除我的应用数据文件夹-手机端方法-2023.3.24日成功 - 哔哩哔哩 (bilibili.com)...

多店铺智能客服,助力店铺销量倍增
近年来电商发展得非常快速,市场竞争也是愈发激烈了。商家不仅需要提高产品和服务的质量,还要争取为自己获取更多的曝光,以此来分散运营的风险和降低经营的成本,所以越来越多的商家也开始转向多平台多店铺运营。但即使运营多个平台…...

会话跟踪技术
cookie 是通过在浏览器第一次请求服务器时,在响应中放入cookie,浏览器接收到cookie后保存在本地,之后每次请求服务器时都将cookie携带到请求头中,用来验证用户身份与状态等。 缺点: 移动端app没有cookiecookie保存在…...

递归算法学习——子集
目录 一,题目解析 二,例子 三,题目接口 四,解题思路以及代码 1.完全深度搜索 2.广度搜索加上深度优先搜索 五,相似题 1.题目 2.题目接口 3.解题代码 一,题目解析 给你一个整数数组 nums ,…...

学习笔记:ROS使用经验(ROS报错)
报错:进程崩溃 ] process has died [pid 734, exit code -5, cmd /root/catkin_ws/devel/lib/pose_graph/pose_graph __name:pose_graph __log:/root/.ros/log/31b0ae1c-3295-11ee-bda9-02429b5737dc/pose_graph-5.log]. log file: /root/.ros/log/31b0ae1c-3295-11…...

设计模式二十四:访问者模式(Visitor Pattern)
用于将数据结构与数据操作分离,使得可以在不修改数据结构的情况下,定义新的操作。访问者模式的核心思想是,将数据结构和操作进行解耦,从而使得新增操作时不必修改数据结构,只需添加新的访问者。主要目的是在不改变数据…...

使用gn+Ninja构建项目
使用下载编译好的gn和ninja报错 先下载了gn的源码[gn.googlesource.com/gn],然后编译报错,就直接下载了了编译号的gn和Ninja,然后写了Helloworld应用的BUILD.gn,然后将"gn\examples\simple_build\build"拷贝至当前目录…...

VMware虚拟机连不上网络
固定ip地址 进入网络配置文件 cd /etc/sysconfig/network-scripts 打开文件 vi ifcfg-ens33 编辑 BOOTPROTO设置为static,有3个值(decp、none、static) BOOTPROTO"static" 打开网络 ONBOOT"yes" 固定ip IPADDR1…...

安防视频监控/视频集中存储/云存储平台EasyCVR平台无法取消共享通道该如何解决?
视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等,视频智能分析平台EasyCVR融合性强、开放度…...

算法通关村-----如何基于数组和链表实现栈
实现栈的基本方法 push(T t)元素入栈 T pop() 元素出栈 Tpeek() 查看栈顶元素 boolean isEmpty() 栈是否为空 基于数组实现栈 import java.util.Arrays;public class ArrayStack<T> {private Object[] stack;private int top;public ArrayStack() {this.stack new…...

day-05 TCP半关闭 ----- DNS ----- 套接字的选项
一、优雅的断开套接字连接 之前套接字的断开都是单方面的。 (一)基于TCP的半关闭 Linux的close函数和windows的closesocket函数意味着完全断开连接。完全断开不仅不能发送数据,从而也不能接收数据。在某些情况下,通信双方的某一方…...

区块链金融项目怎么做?
区块链技术的兴起引发了金融领域的变革,为金融行业带来了前所未有的机遇与挑战。在这个快速发展的领域中,如何在区块链金融领域做出卓越的表现?本文将从专业性和思考深度两个方面,探讨区块链金融的发展路径,并为读者提…...

Redis与数据库保持一致
参考链接 先更新数据库,再更新redis 存在漏洞,如果更新Redis失败,仍然会导致不一致 先删Redis,再更新数据库并同步数据到Redis 存在漏洞,多线程情况下,线程1删除redis后,还是有可能被其他线程读取旧的数据…...