当前位置: 首页 > news >正文

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 = 6

b, 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 main

import (
    "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) //延时15s
    fmt.Println("this is a main goroutine")
}

总结

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

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

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

相关文章:

  • 使用Spreadsheet Compare工具对比Excel文件差异
  • linux环境下使用sort命令完成常见排序操作
  • 关于数据一致性的思考
  • linux环境下sed命令的基础用法
  • 学习cmake从成功编译一个小程序开始
  • linux环境下使用netstat命令查看网络信息
  • 简单聊聊01世界中编码和解码这对磨人的小妖儿
  • C/C++中有符号数隐式类型转换成无符号数需注意的问题
  • system_clock::now()和time()时间函数混用带来的踩坑经历
  • 2020年终总结!新的起航,新的征程
  • 在比较Linux和Windows命令差异时意外发现了Windows Terminal
  • 记一次解决Intel 9462无线网卡的笔记本安装Ubuntu16.04后无法连接WIFI问题的艰难历程
  • 启用make多任务参数让构建过程加速完成
  • C++中一些方便的算法函数和吃不够的语法糖
  • C/C++中string和int相互转换的常用方法
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 2017年终总结、随想
  • bearychat的java client
  • Elasticsearch 参考指南(升级前重新索引)
  • input的行数自动增减
  • Java Agent 学习笔记
  • JAVA多线程机制解析-volatilesynchronized
  • js操作时间(持续更新)
  • SQL 难点解决:记录的引用
  • Vim Clutch | 面向脚踏板编程……
  • Yii源码解读-服务定位器(Service Locator)
  • 代理模式
  • 回顾 Swift 多平台移植进度 #2
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 一道面试题引发的“血案”
  • 一天一个设计模式之JS实现——适配器模式
  • 责任链模式的两种实现
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • 阿里云ACE认证学习知识点梳理
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • #控制台大学课堂点名问题_课堂随机点名
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (13):Silverlight 2 数据与通信之WebRequest
  • (day6) 319. 灯泡开关
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (四)模仿学习-完成后台管理页面查询
  • (一)Thymeleaf用法——Thymeleaf简介
  • (一)为什么要选择C++
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (转)C#调用WebService 基础
  • .a文件和.so文件
  • .form文件_SSM框架文件上传篇
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET Core中的去虚
  • .Net(C#)自定义WinForm控件之小结篇