Go语言在解决实际问题时的优点与不便

2023-12-04 00:38

本文主要是介绍Go语言在解决实际问题时的优点与不便,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • Go 语言
  • 不便之处
    • 三目运算符
    • if 单行语句也要加大括号
  • 优秀特性
    • 多个变量同时赋值
    • defer 声明
    • goroutine 并发
  • 总结

前言

Go语言,全称golang,是Google开发的一种静态强类型、编译型、并发型并具有垃圾回收功能的编程语言。 从2007年末由 Robert Griesemer、Rob Pike、Ken Thompson 主持开发,其中的 Ken Thompson 可是和 Dennis Ritchie 一起发明了C语言的大佬。Go 语言于2009年11月正式宣布成为开放源代码项目, 并在2012年初,发布了Go 1.0稳定版本,此后便开启了稳步发展的道路。

Go 语言

作为一个从2007年开始诞生的语言,在庞大的语言家族中算是一个晚辈,和C++、Python这种老牌语言相比查了将近20年,和 C 语言相比资历就更低了,但是这个新晋的语言在 Google 光环的强大加持下也在飞速发展着,由于前辈们在发展的途中趟了很多坑,所以 Go 在发明之初就避免了其他语言的很多不便,可以说是站在巨人的肩膀上发展起来的。

但是即便这样,Go 语言的特点也不能被所有人喜欢,和许多人一样,我在学习这门语言的过程中也发现一些很方便特性和一些不太方便的特点,下面简单说几个点,有不对的地方希望小伙伴能及时指出,防止我在错误的思想上越走越远(怎么有种新闻发言稿的感觉~)。

不便之处

这里的不便之处只是我在使用过程中感觉不太方便,可能很多人并没有这个感觉,或许还有很多其他的解决方法和替代方案,烦请小伙伴能指点一下。

三目运算符

这个三目运算符是个很常用的逻辑处理部件,也是我在逻辑中经常使用到的,在Python、Lua等语言中也不存在,但是我都找到了简单的替代方式,但是在Go 中不得不写成中规中矩的 if 条件判断,这让很多算法的解题代码看起来并不那么优雅,比如一个简单的约瑟夫环问题:

N个人围成一圈,从第一个人从开始报数,报到m的人出圈,剩下的人继续从1开始报数,报到m的人出圈;如此往复,直到所有人出圈,输出最后一个出圈人最初始的编号。

这个问题的解法最简单的是模拟法,使用数组模拟一个环来按照规则运行,最后一个出圈的人的编号就可以输出到结果,还有一种思路就是找规律,可以找到出圈前后的序号对应关系,进而写出一行代码的解决方案。

// 索引从0开始,只要对结果加1就好了
int joseph_ring(int n, int m) {return n == 1 ? 0 : (joseph_ring(n - 1, m) + m) % n
}

但是在没有三目运算符的 Go 中要实现这个算法,就不得不多写几行了,和 C 语言相比就没有那么简洁了。

func joseph_ring(n int, m int) int {if n == 1 {return 0}return (joseph_ring(n - 1, m) + m) % n
}

if 单行语句也要加大括号

Go 语言本身带有自己的格式化命令,可以保证编写时不同的缩进样式格式化之后得到相同的代码,if 后面的条件语句可以不加小括号,但是后面的语句块必须加大括号,这样的规定对于我经常写的代码有点不太友好,比如下面这些C++代码:

if (a > 0)break;if (b < 0)continue;if (c == 0)return;

有时候为了看起来紧凑,可能会写成这样:

if (a > 0) break;
if (b < 0) continue;
if (c == 0) return;

但是放到 Go 语言中,就不得不写成好几行了,并且还要加大括号,看起来代码有些松散。

if a > 0 {break;
}if b < 0 {continue;
}if c == 0 {return;
}

优秀特性

上面提到了 Go 语言中不方便的地方,现在可以来说说 Go 语言相对于 C、C++ 更优越的特性:

多个变量同时赋值

在 C++ 中交换两个变量的通常使用中间变量来完成,比如交换 ab 两个变量的值:

int a = 1;
int b = 6;int tmp = a;
a = b;
b = tmp;

针对于这种整形的变量,一些大牛们发明了特殊的算法来处理,避免使用中间变量:

int a = 1,;
int b = 6;a = a ^ b
b = b ^ a
a = a ^ b

但是在 Go语言中这种情况非常好处理,直接从左到右依次赋值就好了

var a int = 1
var b int = 6b, a = a, b

defer 声明

defer 可以用于在当前函数返回前执行一些清理代码,而不管此函数如何退出。defer 在函数中可以随时出现,这使得清理代码可以尽可能在需要清理的地方运行,比如我们常常要释放申请的资源,常见的需要释放的资源有文件描述符:

file, err := os.Open(fileName)
if err != nil {return
}
defer file.Close()

有了 defer 终于不再在担心,资源没回收的问题,也不用在各个提前返回的条件分支中添加释放资源的重复代码了。

goroutine 并发

goroutine 是Go并行设计的核心,说到底其实就是协程,但是它比线程更小并且在Go语言内部帮你实现了这些 goroutine 之间的内存共享。执行 goroutine 只需要极少的栈内存,可同时运行成千上万个并发任务。goroutine 一定程度上比 thread 更易用、更高效、更轻便。

使用起来也非常方便,创建 goroutine 只需在函数调用语句前添加 go 关键字,就可以创建并发执行单元。开发人员无需了解任何执行细节,调度器会自动将其安排到合适的系统线程上执行,这是解放生产力的又一创举,简单示例代码如下:

package mainimport ("fmt""time"
)func new_task() {for i := 0; i < 10; i++ {fmt.Println("this is a newTask")time.Sleep(time.Second) //延时1s}
}func main() {for i := 0; i < 3; i++ {go new_task() //新建一个协程, 新建一个任务}time.Sleep(time.Second * 15) //延时15sfmt.Println("this is a main goroutine")
}

总结

  • Go 语言作为编程语言中的新晋小弟,吸收了前人的经验,现阶段发展迅猛
  • 虽然 Go 出于一些目的规定了语言的标准,但是类似于没有三目运算符这种特点还是有些不方便
  • Go 这门语言还很年轻,相信随着不断发展它会越来越优秀,但没有任何语言是完美无缺的

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

陪伴是最长情的告白,而守护是最沉默的陪伴。国庆中秋双节合并,放假了,陪家人待在一起真的很开心,什么都不用做,就静静的待在一起很满足,聊聊天、抬抬杠,假期嗖嗖嗖地溜掉了~

这篇关于Go语言在解决实际问题时的优点与不便的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/451467

相关文章

Vue3绑定props默认值问题

《Vue3绑定props默认值问题》使用Vue3的defineProps配合TypeScript的interface定义props类型,并通过withDefaults设置默认值,使组件能安全访问传入的... 目录前言步骤步骤1:使用 defineProps 定义 Props步骤2:设置默认值总结前言使用T

504 Gateway Timeout网关超时的根源及完美解决方法

《504GatewayTimeout网关超时的根源及完美解决方法》在日常开发和运维过程中,504GatewayTimeout错误是常见的网络问题之一,尤其是在使用反向代理(如Nginx)或... 目录引言为什么会出现 504 错误?1. 探索 504 Gateway Timeout 错误的根源 1.1 后端

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

解决升级JDK报错:module java.base does not“opens java.lang.reflect“to unnamed module问题

《解决升级JDK报错:modulejava.basedoesnot“opensjava.lang.reflect“tounnamedmodule问题》SpringBoot启动错误源于Jav... 目录问题描述原因分析解决方案总结问题描述启动sprintboot时报以下错误原因分析编程异js常是由Ja

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

MySQL 表空却 ibd 文件过大的问题及解决方法

《MySQL表空却ibd文件过大的问题及解决方法》本文给大家介绍MySQL表空却ibd文件过大的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录一、问题背景:表空却 “吃满” 磁盘的怪事二、问题复现:一步步编程还原异常场景1. 准备测试源表与数据

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对

解决Nginx启动报错Job for nginx.service failed because the control process exited with error code问题

《解决Nginx启动报错Jobfornginx.servicefailedbecausethecontrolprocessexitedwitherrorcode问题》Nginx启... 目录一、报错如下二、解决原因三、解决方式总结一、报错如下Job for nginx.service failed bec