广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Go语言区别于其他语言的特性
  • 901
分享到

Go语言区别于其他语言的特性

2024-04-02 19:04:59 901人浏览 八月长安
摘要

目录1. Go 总是在构建中包含二进制文件2. Go 没有针对程序依赖的集中托管服务3. Go 是按值调用的4. 'defer' 关键字5. Go 采用了函数式编程的最佳特性6. G

前言:

随着编程语言的发展,Go 还很年轻。它于 2009 年 11 月 10 日首次发布。其创建者Robert Griesemer Rob Pike Ken ThompsonGoogle 工作,在那里大规模扩展的挑战激励他们将 Go 设计为一种快速有效的编程解决方案,用于具有大型代码库、管理由多个开发人员,具有严格的性能要求,并跨越多个网络和处理核心。 Go 的创始人在创建他们的新语言时也借此机会学习了其他编程语言的优点、缺点和漏洞。结果是一种干净、清晰和实用的语言,具有相对较少的命令和功能集。

1. Go 总是在构建中包含二进制文件

Go 运行时提供内存分配、垃圾收集、并发支持和网络等服务。它被编译到每个 Go 二进制文件中。这与许多其他语言不同,其中许多语言使用需要与程序一起安装才能正常工作的虚拟机

将运行时直接包含在二进制文件中使得分发和运行 Go 程序变得非常容易,并避免了运行时和程序之间的不兼容问题。pythonRuby javascript 等语言的虚拟机也没有针对垃圾收集和内存分配进行优化,这解释了 Go 相对于其他类似语言的优越速度。例如,Go 将尽可能多的存储在堆栈中,其中数据按顺序排列以便比堆更快地访问。稍后会详细介绍。

关于 Go 的静态二进制文件的最后一件事是,因为不需要运行外部依赖项,所以它们启动得非常快。如果您使用Google App Engine 之类的服务,这是一种在 Google Cloud 上运行的平台即服务,它可以将您的应用程序缩减到零实例以节省云成本,这将非常有用。当收到新请求时,App Engine 可以在眨眼间启动 Go 程序的一个实例。在 Python node 中的相同体验通常会导致 3-5 秒(或更长时间)的等待,因为所需的虚拟环境也会与新实例一起启动。

2. Go 没有针对程序依赖的集中托管服务

为了访问已发布的 Go 程序,开发人员不依赖集中托管的服务,例如Java 的Maven CentralJavaScript的NPM注册表。相反,项目通过其源代码存储库(最常见的是 GitHub)共享。在go install命令行允许以这种方式下载库。 为什么我喜欢这个功能?我一直认为像 Maven CentralPIP 和 NPM 这样的集中托管的依赖服务有点令人生畏的黑盒子,也许可以抽象出下载和安装依赖项的麻烦,但不可避免地会在依赖项错误时引发可怕的心跳停止发生。

此外,将的的模块提供给其他人就像将其放入版本控制系统一样简单,这是分发程序的一种非常简单的方式。

3. Go 是按值调用的

在 Go 中,当你提供一个原始值(数字、布尔值或字符串)或一个结构体(类对象的粗略等价物)作为函数的参数时,Go 总是会复制变量的值。

JavaPython JavaScript 等许多其他语言中,原语是按值传递的,但对象(类实例)是按引用传递的,这意味着接收函数实际上接收的是指向原始对象的指针,而不是其副本。在接收函数中对对象所做的任何更改都会反映在原始对象中。

在 Go 中,结构体和原语默认按值传递,可以选择传递指针,通过使用星号运算符:


// 按值传递
func MakeNewFoo(f Foo ) (Foo, error) { 
   f.Field1 = "New val" 
   f.Field2 = f.Field2 + 1 
   return f, nil 
}

上述函数接收 Foo 的副本并返回一个新的 Foo 对象。


// 通过引用传递
func MutateFoo(f *Foo ) error { 
   f.Field1 = "New val" 
   f.Field2 = 2 
   return nil 
}

上面的函数接收一个指向 Foo 的指针并改变原始对象。

按值调用与按引用调用的这种明显区别使您的意图显而易见,并降低了调用函数无意中改变传入对象的可能性(当它不应该发生时(许多初学者开发人员很难做到这一点)握紧)。

正如麻省理工总结的:“可变性使得理解你的程序在做什么变得更加困难,并且更难以执行契约”

此外,按值调用显着减少了垃圾收集器的工作,这意味着应用程序更快、内存效率更高。这篇文章得出的结论是,指针追踪(从堆中检索指针值)比从连续堆栈中检索值慢 10 到 20 倍。要记住的一个很好的经验法则是:从内存中读取的最快方法是顺序读取,这意味着将随机存储在 RAM 中的指针数量减少到最少。

4. 'defer' 关键字

nodejs 中,在我开始使用knex.js之前,我会通过创建一个数据库池来手动管理我的代码中的数据库连接,然后在每个函数中从池中打开一个新连接,一旦所需的数据库 CRUD 功能已完成。

这有点像维护噩梦,因为如果我没有在每个函数结束时释放连接,未释放的数据库连接的数量会慢慢增长,直到池中没有更多可用连接,然后中断应用程序。

现实情况是,程序经常需要释放、清理和拆除资源、文件、连接等,因此 Go 引入了defer关键字作为管理这些的有效方式。

任何以defer开头的语句都会延迟对它的调用,直到周围的函数退出。这意味着您可以将清理/拆卸代码放在函数的顶部(很明显),知道一旦函数完成它就会如此。


func main() {                        
    if len(os.Args) < 2 {   
        log.Fatal("no file specified")
    }  
    f, err := os.Open(os.Args[1])                        
    if err != nil {                         
        log.Fatal(err)                        
    }                        
    defer f.Close()                        
    data := make([]byte, 2048)                        
    for {                         
        count, err := f.Read(data)                                               
        os.Stdout.Write(data[:count])                        
        if err != nil {                          
            if err != io.EOF {                           
                log.Fatal(err)                          
            }                          
            break                         
        }                        
    }                       
}

在上面的例子中,文件关闭方法被推迟了。我喜欢这种在函数顶部声明你的内务处理意图的模式,然后忘记它,知道一旦函数退出它就会完成它的工作。

5. Go 采用了函数式编程的最佳特性

函数式编程是一种高效且富有创造性的范式,幸运的是 Go 采用了函数式编程的最佳特性。在Go中:

  • 函数是值,这意味着它们可以作为值添加到映射中,作为参数传递给其他函数,设置为变量,并从函数返回(称为“高阶函数”,在 Go 中经常使用装饰器创建中间件图案)。
  • 可以创建和自动调用匿名函数。
  • 在其他函数内声明的函数允许闭包(在函数内声明的函数能够访问和修改在外部函数中声明的变量)。在惯用的 Go 中,闭包被广泛使用来限制函数的范围,并设置函数然后在其逻辑中使用的状态。


func StartTimer (name string) func(){
    t := time.Now()
    log.Println(name, "started")
    return func() {
        d := time.Now().Sub(t)
        log.Println(name, "took", d)
    }
}
func RunTimer() {
    stop := StartTimer("My timer")
    defer stop()
    time.Sleep(1 * time.Second)
}

上面是一个闭包的例子。'StartTimer' 函数返回一个新函数,它通过闭包可以访问在其出生范围内设置的 't' 值。然后,此函数可以将当前时间与“t”的值进行比较,从而创建一个有用的计时器。感谢Mat Ryer的这个例子。

6. Go 有隐式接口

任何阅读过有关SOLID编码和设计模式的文献的人都可能听说过“优先组合胜过继承”的口头禅。简而言之,这表明您应该将业务逻辑分解为不同的接口,而不是依赖于来自父类的属性和逻辑的分层继承。

另一个流行的方法是“为接口编程,而不是实现”: api 应该只发布其预期行为的契约(其方法签名),而不是有关如何实现该行为的详细信息。

这两者都表明接口在现代编程中的重要性。

因此,Go 支持接口也就不足为奇了。事实上,接口是 Go 中唯一的抽象类型。

然而,与其他语言不同,Go 中的接口不是显式实现的,而是隐式实现的。具体类型不声明它实现了接口。相反,如果为该具体类型设置的方法集包含底层接口的所有方法集,则Go 认为该对象实现了 interface

这种隐式接口实现(正式称为结构类型)允许 Go 强制执行类型安全和解耦,保持动态语言中表现出的大部分灵活性。

相比之下,显式接口将客户端和实现绑定在一起,例如,在 Java 中替换依赖项比在 Go 中困难得多。


// 这是一个接口声明(称为Logic)
type Logic interface { 
    Process (data string) string 
}

type LogicProvider struct {}
// 这是 LogicProvider 上名为“Process”的方法 struct
 func (lp LogicProvider) Process (data string) string { 
    // 业务逻辑
}
// 这是具有 Logic 接口作为属性的客户端结构
type Client struct { 
    L Logic 
}
func(c Client) Program() { 
    // 从某处获取数据
    cLProcess(data) 
}
func main() { 
    c := Client { 
        L: LogicProvider{},  
     } 
    c.Program() 
}

LogicProvider 中没有任何声明表示它符合Logic接口。这意味着客户端将来可以轻松替换其逻辑提供程序,只要该逻辑提供程序包含底层接口 ( Logic ) 的所有方法集。

7.错误处理

Go 中的错误处理方式与其他语言大不相同。简而言之,Go 通过返回一个 error 类型的值作为函数的最后一个返回值来处理错误。

当函数按预期执行时,错误参数返回nil,否则返回错误值。调用函数然后检查错误返回值,并处理错误,或抛出自己的错误。


// 函数返回一个整数和一个错误
func calculateRemainder(numerator int, denominator int) ( int, error ) { 
   //
   if denominator == 0 { 
      return 9, errors.New("denominator is 0"
    }
   // 没有错误返回
   return numerator / denominator, nil
 }

Go 以这种方式运行是有原因的:它迫使编码人员考虑异常并正确处理它们。传统的 try-catch 异常还会在代码中添加至少一个新的代码路径,并以难以遵循的方式缩进代码。Go 更喜欢将“快乐路径”视为非缩进代码,在“快乐路径”完成之前识别并返回任何错误。

8.并发

可以说是 Go 最著名的特性,并发允许处理在机器或服务器上的可用内核数量上并行运行。当单独的进程不相互依赖(不需要顺序运行)并且时间性能至关重要时,并发性最有意义。这通常是 I/O 要求的情况,其中读取或写入磁盘或网络的速度比除最复杂的内存中进程之外的所有进程慢几个数量级。 函数调用前的“ go ”关键字将同时运行该函数。


func process(val int) int { 
   // 用 val 做一些事情
}
// 对于 'in' 中的每个值,同时运行 process 函数,
// 并将 process 的结果读取到 'out'
 func runConcurrently(in <-chan int, out chan<- int){ 
   go func() { 
       for val := range in { 
            result := process(val) 
            out <- result   
       } 
   } 
}

Go 中的并发是一项深入且相当高级的功能,但在有意义的地方,它提供了一种有效的方法来确保程序的最佳性能。

9. Go 标准库

Go 有一个“包含电池”的理念,现代编程语言的许多要求都被纳入标准库,这使程序员的生活变得更加简单。 如前所述,Go 是一种相对年轻的语言,这意味着标准库中可以满足现代应用程序的许多问题/要求。

一方面,Go 为网络(特别是 Http/2)和文件管理提供了世界一流的支持。它还提供原生 JSON 编码和解码。因此,设置服务器来处理 HTTP 请求并返回响应(JSON 或其他)非常简单,这解释了 Go 在基于 REST 的 HTTP WEB 服务开发中的流行。

正如Mat Ryer还指出的那样,标准库是开源的,是学习 Go 最佳实践的绝佳方式。

到此这篇关于Go 有别于其他语言的九个特性 的文章就介绍到这了,更多相关Go 有别于其他语言的特性 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Go语言区别于其他语言的特性

本文链接: https://www.lsjlt.com/news/137548.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go语言区别于其他语言的特性
    目录1. Go 总是在构建中包含二进制文件2. Go 没有针对程序依赖的集中托管服务3. Go 是按值调用的4. 'defer' 关键字5. Go 采用了函数式编程的最佳特性6. G...
    99+
    2022-11-12
  • C++语言与其他语言有什么区别
    本篇内容主要讲解“C++语言与其他语言有什么区别”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++语言与其他语言有什么区别”吧!本文着重进行对C++语言来说,在语法上要简单得多,因此初学者很容...
    99+
    2023-06-17
  • C语言和其他编程语言的区别有哪些
    这篇文章主要讲解了“C语言和其他编程语言的区别有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言和其他编程语言的区别有哪些”吧!  一、静态内存  内存管理---存储模型  存储模型...
    99+
    2023-06-17
  • Go语言跟python等其他语言作对比
    本篇内容介绍了“Go语言跟python等其他语言作对比”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!设计Go是为了解决当时Google开发遇...
    99+
    2023-06-16
  • go语言和其他语言有什么不同
    go语言和其他语言的不同之处有:1、Go语言的语法对比其他语言更加直观,减少了开发和维护的时间和精力;2、与其他语言需要不同机制实现并发不同,Go语言通过协程和通道提供了轻量级的并发编程方式;3、与其他语言需要手动管理内存相比,Go语言可以...
    99+
    2023-07-10
  • Python和其他语言有什么区别
    本篇内容介绍了“Python和其他语言有什么区别”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!问:谈谈对 Python 和其他语言的区别?答...
    99+
    2023-06-19
  • Python代码显得Pythonic(区别于其他语言的写法)
    目录一、字符串二、运算三、赋值四、变量命名五、提升代码可读性(一)避免用分号;在一行内些多条语句(二)避免用\符号来换行(三)if-else三元表达式一、字符串 对于字符串连接,相比...
    99+
    2022-11-13
  • Golang与其他语言不同的九个特性
    目录1. Go 总是在构建中包含二进制文件2. Go 没有针对程序依赖的集中托管服务3. Go 是按值调用的4. ‘defer' 关键字6. Go 有隐式接口7.错误处理8.并发9....
    99+
    2022-11-12
  • go语言 golang 区别
    随着互联网技术的不断发展,各种编程语言也层出不穷。其中,Go语言(或称为Golang)是近年来备受瞩目的一种编程语言。那么,Go语言和其他编程语言相比较,有什么特别之处呢?在本文中,我们将探讨Go语言与其他编程语言的不同之处。一、Go语言的...
    99+
    2023-05-14
  • r语言与go语言有啥区别
    r语言与go语言区别有:1、R语言是一种专门用于统计分析和数据可视化的语言,Go语言是一种面向并发的编程语言;2、在适用领域上,R语言主要用于数据分析和统计建模,Go语言主要用于构建网络服务和分布式系统;3、在编程风格上,R语言更接近脚本语...
    99+
    2023-07-13
  • c语言与go语言的区别有哪些
    小编给大家分享一下c语言与go语言的区别有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!区别:1、C语言源文件的扩展名是“.h”和“.c”,Go语言源文件的扩展名是“.go”。2、C语言中通过文件来管理代码,Go语言中...
    99+
    2023-06-06
  • GO语言的日志响应速度比其他语言快多少?
    随着云计算、大数据、人工智能等技术的不断发展,日志系统的重要性越来越凸显出来。在开发过程中,我们经常会使用日志来记录程序的运行状态,以便于分析和调试。但是,日志系统的性能却往往成为制约程序性能的瓶颈。因此,在选择日志框架时,我们需要考虑其...
    99+
    2023-07-02
    索引 日志 响应
  • 让JavaScript 区别于其它语言的是什么
    这篇文章给大家介绍让JavaScript 区别于其它语言的是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。只有了解了原型继承,你才能说你懂 JS,原型影响着对象的工作方式。原型继承...
    99+
    2022-10-19
  • Go语言相对于其他编程语言,在云计算领域有哪些优势?
    随着云计算技术的快速发展,越来越多的企业使用云计算来管理和存储数据。而云计算的核心技术就是编程语言。Go语言作为一种相对新兴的编程语言,在云计算领域也有着自己的优势。本文将探讨Go语言在云计算领域的优势。Go语言的异步编程模型在云计算中,异...
    99+
    2023-05-19
    云计算 Go语言 优势
  • Laravel 中的路径索引:使用 Go 语言还是其他语言更好?
    Laravel 是一个流行的 PHP 框架,它提供了许多便利的功能和工具,让开发者能够更加快速和高效地构建 Web 应用程序。其中一个重要的功能就是路径索引,这个功能可以让开发者轻松地处理和管理应用程序中的路径。 在 Laravel 中,路...
    99+
    2023-08-20
    laravel 索引 path
  • go语言特性有哪些
    go语言特性有:1、简洁易学,降低学习门槛,尤其适合初学者;2、高效性能,能够高效地处理并发任务,从而提升程序的性能;3、并发支持,可以轻松地利用goroutine来实现并发操作,而不需要手动管理线程和锁;4、内置工具,以显著提高开发效率和...
    99+
    2023-07-31
  • 分布式日志处理中,Go语言和其他语言有何不同?
    在分布式系统中,日志处理是非常重要的一环。分布式系统中产生的日志量很大,需要对这些日志进行收集、存储、分析等操作。在这个过程中,不同的编程语言有着各自的优缺点。 Go语言是一门以并发为核心的编程语言,它的并发模型非常高效、简单、安全。在分布...
    99+
    2023-09-30
    分布式 日志 http
  • go语言nil有哪些特性
    本文小编为大家详细介绍“go语言nil有哪些特性”,内容详细,步骤清晰,细节处理妥当,希望这篇“go语言nil有哪些特性”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。nil是Go语言中一个预定义好的标识符,表示空...
    99+
    2023-07-05
  • go语言有什么新特性
    Go语言的新特性主要集中在以下几个方面:1. 模块化支持:Go 1.11引入了Go模块的概念,可以更方便地管理和复用代码。通过go....
    99+
    2023-10-12
    Go语言
  • go语言和c语言在指针上有什么区别
    区别:1、go语言可以使用new关键字来分配内存创建指定类型的指针,而c语言不行。2、c语言中数组名arr代表的是数组首元素的地址,相当于“&arr[0]”;go语言中数组名arr不代表数组首元素的地址,代表的是整个数组的值。3、g...
    99+
    2023-05-14
    C语言 指针 go语言 Golang Go
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作