Go的语言特性总结

作者:网络    软件教程库   2020-05-12

写在前面:
近来关于对golang的讨论有很多,七牛的几个大牛们也断定go语言在未来将会快速发展,并且很可能会取代java成为互联网时代最受欢迎的编程语言。go语言是google推出的编程语言,在已经成功的给世人创造了改变人们生活的操作系统之后,google似乎感觉有必要再为世人带来一款强大的编程语言,而go语言依靠自己众多友好的特性也不负众望正在被开发者接触,我有幸在学习高性能并发编程的时候认识了go语言,在了解了go的一些特性之后决定系统的学习一番。我发现关于go的学习资料并不多,以至于我需要自己写一些东西。这里的内容大多来自七牛团队的《go语言编程》一书。这里也会按照书中组织的章节进行学习。当然如果一些知识点事互联网上已经有的,这里直接进行转载了。
-written by lingtao in nanjing.

http://blog.csdn.net/michael_kong_nju/article/details/45423197

按照书中说的,go语言具有以下的特征,下面我们分别来进行介绍。
自动垃圾回收
更丰富的内置类型
函数多返回值
错误处理
匿名函数和闭包
类型和接口
并发编程
反射
语言交互性

1. 自动垃圾回收

从c到c++,从程序性能的角度来考虑,这两种语言允许程序员自己管理内存,包括内存的申请和释放等。因为没有垃圾回收机制所以c/c++运行起来速度很快,但是随着而来的是程序员对内存使用上的很谨小慎微的考虑。因为哪怕一点不小心就可能会导致“内存泄露”使得资源浪费或者“野指针”使得程序崩溃等,尽管c++11后来使用了智能指针的概念,但是程序员仍然需要很小心的使用。后来为了提高程序开发的速度以及程序的健壮性,java和c#等高级语言引入了gc机制,即程序员不需要再考虑内存的回收等,而是由语言特性提供垃圾回收器来回收内存。但是随之而来的可能是程序运行效率的降低。
“go语言作为一门新生的开发语言,当然不能忽略内存管理这个问题。又因为go语言没有c++
这么“强大”的指针计算功能,因此可以很自然地包含垃圾回收功能。因为垃圾回收功能的支持,开发者无需担心所指向的对象失效的问题,因此go语言中不需要delete关键字,也不需要free()方法来明确释放内存”.

2. 更丰富的内置类型

其实作为一种新兴的语言,如果仅仅是为了某种特定的用途那么可能其内置类型不是很多,仅需要能够完成我的功能即可,但是go语言“不仅支持几乎所有语言都支持的简单内置类型(比如整型和浮点型等)外,还支持一些其他的高级类型,比如字典类型,map要知道这些类型在其他语言中都是通过包的形式引入的外部数据类型。数组切片(slice),类似于c++ stl中的vector,在go也是一种内置的数据类型作为动态数组来使用。这里满有一个颇为简单的解释:”既然绝大多数开发者都需要用到这个类型,为什么还非要每个人都写一行import语句来包含一个库?”

3. 支持函数多返回值

在c,c++中,包括其他的一些高级语言是不支持多个函数返回值的。但是这项功能又确实是需要的,所以在c语言中一般通过将返回值定义成一个结构体,或者通过函数的参数引用的形式进行返回。而在go语言中,作为一种新型的语言,目标定位为强大的语言当然不能放弃对这一需求的满足,所以支持函数多返回值是必须的,例如:

 func getname()(firstname, middlename, lastname, nickname string){
 return "may", "m", "chen", "babe" } //定义了一个多返回值的函数getname
 
 fn, mn, ln, nn := getname()      //调用赋值
  _, _, lastname, _ := getname() //缺省调用

4. 错误处理

在传统的oop编程中,为了捕获程序的健壮性需要捕获异常,使用的方法大都是try() catch{}模块,例如, 在下面的java代码中,可能需要的操作是:

connection conn = ...;
try {
    statement stmt = ...;
    ...//别的一些异常捕获
finally {
    stmt.close();
    }
finally {
    conn.close(); 
}

而在go中引入了三个关键字,分别是 defer、panic和recover,其中使用defer关键字语句的含义是不管程序是否出现异常,均在函数退出时自动执行相关代码。
所以上面你的java代码用go进程重写只有两行:

conn := ...
defer conn.close()

另外两个关键词后面再讨论。所以“go语言的错误处理机制可以大量减少代码量,让开发者也无需仅仅为了程序安全性而添加大量一层套一层的try-catch语句。这对于代码的阅读者和维护者来说也是一件很好的事情,因为可以避免在层层的代码嵌套中定位业务代码。”

5. 匿名函数和闭包

关于这个功能介绍的不多,大概就是说go中的函数也可以作为参数进行传递:
“在go语言中,所有的函数也是值类型,可以作为参数传递。go语言支持常规的匿名函数和闭包,比如下列代码就定义了一个名为f的匿名函数,开发者可以随意对该匿名函数变量进行传递和调用:
f := func(x, y int) int {
return x + y
}

6. 类型和接口

这个特性是go在实现opp时候的一些特性,主要有这么几点:
第一: go语言没有很复杂的面向对象的概念,即没有继承和重载,其类型更像是c中的struct,并且直接使用了struct关键字,仅仅是最基本的类型组合功能。但是,尽管不支持这些语法特性,但是go的oop却同样可以实现这些功能,只是实现的形式上会有不同而已。
即这里需要介绍的“非侵入型”接口的概念。
举个例子:
在c++中,一般会这样定义一个接口和类型的

// 抽象接口
interface ifly
{
virtual void fly()=0;
};
// 实现类
class bird : public ifly
{
public:
bird() {}
virtual ~bird() {}
void fly()
{
// 以鸟的方式飞行
}
};
//使用的时候
void main()
{
ifly* pfly = new bird();
pfly-fly();
delete pfly;
}需要你自己以虚函数的形式定义一个接口,并且让类型继承这个接口并重写虚方法。在使用的时候需要进行动态绑定。
而在go中实现相同的功能,你只需要
type bird struct {

}
func (b *bird) fly() {
// 以鸟的方式飞行
}
type ifly interface {
fly()
}
func main() {
var fly ifly = new(bird)
fly.fly()
}
可以看出,“虽然bird类型实现的时候,没有声明与接口ifly的关系,但接口和类型可以直
接转换,甚至接口的定义都不用在类型定义之前,这种比较松散的对应关系可以大幅降低因为接
口调整而导致的大量代码调整工作”。

7. 并发编程

其实到目前为止,最吸引我的就是这个特性,而且我之前说了如果不是因为要做服务器的高并发我可能根本就不知道go这种语言,在上一篇文章http://blog.csdn.net/michael_kong_nju/article/details/45420047 中讨论了为什么go可以实现大规模的并发的原理,这里不做详细的介绍,只给出实现方法,即
“go语言引入了goroutine概念,它使得并发编程变得非常简单。通过使用goroutine而不是裸用操作系统的并发机制,以及使用消息传递来共享内存而不是使用共享内存来通信,go语言让并发编程变得更加轻盈和安全。通过在函数调用前使用关键字go,我们即可让该函数以goroutine方式执行,goroutine是一种比线程更加轻盈、更省资源的协程。”
“同时,go语言实现了csp(通信顺序进程,communicating sequential process)模型来作为goroutine间的推荐通信方式,在csp模型中,一个并发系统由若干并行运行的顺序进程组成,每个进程不能对其他进程的变量赋值。进程之间只能通过一对通信原语实现协作。go语言用channel(通道)这个概念来轻巧地实现了csp模型。channel的使用方式比较接近unix系统中的管道(pipe)概念,可以方便地进行跨goroutine的通信。”
“另外,另外,由于一个进程内创建的所有goroutine运行在同一个内存地址空间中,因此如果不同的goroutine不得不去访问共享的内存变量,访问前应该先获取相应的读写锁。go语言标准库中的sync包提供了完备的读写锁功能。”

8. 支持反射

这里的反射(reflecttion)和java中的反射类似,可以用来获取对象类型的相信信息,并动态操作对象。因为反射可能会对程序的可读性有很大的干扰,所以,在go中只是在特别需要反射支持的地方才实现反射的一些功能。“反射最常见的使用场景是做对象的序列化(serialization,有时候也叫marshal unmarshal)。例如,go语言标准库的encoding/json、encoding/xml、encoding/gob、encoding/binary等包就大量依赖于反射功能来实现。”

9. 语言的交互性

这里的交互性主要是和c的交互性,之所以这样是因为go语言的开发者是最初贝尔实验室创建unix系统以及c语言的一般人,包括:
肯·汤普逊(ken thompson,http://en.wikipedia.org/wiki/ken_thompson):设计了b语言和c语言,创建了unix和plan 9操作系统,1983年图灵奖得主,go语言的共同作者。
在go语言中直接重用了大部份的c模块,这里称为cgo.cgo允许开发者混合编写c语言代码,然后cgo工具可以将这些混合的c代码提取并生成对于c功能的调用包装代码。开发者基本上可以完全忽略这个go语言和c语言的边界是如何跨越的。
例如书中一个例子,在go语言中直接调用了c标准库的puts函数。

package main
/*
#include stdio.h
*/
import "c"
import "unsafe"
func main() {
cstr := c.cstring("hello, world")
c.puts(cstr)
c.free(unsafe.pointer(cstr))
}

以上就是书中总结的go语言的9大特性,这里面我看完之后根据自己的体会以及书中的一些总结进行了汇总。对于想了解go这么语言,以及准备进入这个领域的人可以对go有一个大概的认识。如果想深入的学习可以去看七牛云存储团队出的《go语言编程》。我后面也会继续学习。

go的语言特性总结

原文地址:http://blog.csdn.net/michael_kong_nju/article/details/45423197

软件教程库 该篇文章地址:https://www.itjcku.com/9999/1091349.html

阅读全部内容


Tags:语言特性总结

返回首页



推荐内容

golang控制channel的出入口

golang控制channel的出入口 我们常常使用channel来在多个goroutine之间做数据通讯,但是cha ...

UVA10479TheHendrieSequence规律

题目大意:一个序列,刚开始由0变到了1,接着往后一个个变化下去 变化的规则是,如果当前数是k,就在这个序列的最后面加上 ...

在不是Activity类中调用Toast和Dialog

有时候我们需要在非activity类中处理一些逻辑,显示toast对话框或者是弹出一个dialog,但是在非activi ...

查询Oraclesql语句中绑定变量值的方法

alter session set nls_date_format = #39;yyyy-mm-dd,hh24:mi:s ...

Hdoj1588GaussFibonacci【矩阵快速幂】

gauss fibonacci time limit: 1000/1000 ms (java/others) m ...

Hdoj5195DZYLovesTopologicalSorting【拓扑】+【线段树】

dzy loves topological sorting time limit: 4000/2000 ms (jav ...

【转自mos文章】使用单条sql来查询出awr中的syatemstatistics

使用单条sql来查询出awr中的syatem statistics 参考自: how to monitor system ...

I.MX6Q(TQIMX6Q/TQE9)学习笔记——新版BSP之u-boot移植

前段时间就开始学习i.mx6q了,但是最近工作实在是忙,间断了一些时间了。为了提高移植效率,还是考虑移植freescal ...

eclipse应用技巧

最近发现eclipse作为ide还是有很多值得探索的使用技巧的,转载一下他人整理好的资源以做分享。 快捷键的使用,加速 ...

Mysql创建数据库的排序规则中文选择哪种编码

mysql中文编码 mysql创建数据库的排序规则 中文 选择哪种编码原文地址:http://blog. ...

线性表简述

一、简单实现增,删,改、查 package datatructs; /** * 表接口 */ public int ...

android测试本地服务调试流程

我今天调试的整个过程 1,安卓发现连不上本地的tomcat 2,使用浏览器直接尝试,发现可以连上 3,怀疑是安卓app和 ...

设计模式1

静态工厂模式,工厂方法模式,抽象工厂模式 工厂方法改进了添加新产品时,静态工厂不满足的开-闭原则;而抽象工厂满足了当产品 ...

c语言文件操作总结

#includelt;stdio.hgt; /********************************** ...

(c#)如果添加的字段中已经有了身份证号码,则年龄和性别和出生年月可得

//把界面文本框里面的身份证号进行提取,以二代身份证为例 model.ecardid = txt_cardno. ...

Scrum时间估算

在新公司里,不懂软件工程的产品经理经常逼迫研发人员作出很不靠谱的时间估算。常见场景有下面这些: 需求未细化的情况下要求给 ...

C++11中uniforminitialization和initializer_list

c++11中出现了uniform initialization的概念: int a1 = {1};//ok int a ...

关于Scrum

最近某些产品经理发出下两周的工作计划的时候,喜欢带上sprint这个字眼,看上去貌似是要走敏捷开发这一套,只可惜,我觉得 ...

输入输出简单解释

;汇编指令,表示程序将被汇编成能在intel386系列及以上的计算机上运行.386;model flat 表明程序使用保 ...

2015第18周五问题即机会

问题即机会,当一切问题都不存在的时候,请问你的机会在哪里? 你能达到怎样的境界,取决于你怎样认识这个世界。对于问题,有人 ...

solr配置方案

http://www.sjsjw.com/kf_cloud/article/44_5945_1823.asp cento ...

什么是二维码?

二维码,业界当然是人人听说,人人用过。 这个话题,我倒是百感交集,我一直认为,我有一种二维码情节。 一方面, 我自认 ...

1475:方格取数

1475: 方格取数 time limit:5 secmemory limit:64 mbsubmit:578solv ...

敏捷开发宣言(一)

原文: inpiduals and interactionsover processes and tools worki ...

(C#)一个项目的配置和增删改查

一、windows窗体项目环境配置步骤 1.文件mdash;gt;新建mdash;gt;项目mdash;gt;windo ...

比例简化

题目描述description 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果。例如,对某一观点表示 ...

sockaddr和sockaddr_in的区别

struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址。 在各种系统调用 ...

基于Html5的智能家居手机客户端设计(一)——找到openhab的rest

今天开始我的毕业设计,基于html5的智能家居手机客户端设计。挑剔了好久,终于找到我可以使用国外开源项目智能家居核心 ...

阅读《大道至简--软件工程实践者的思想》有感(3)

阅读完《大道至简--软件工程实践者的思想》,明白了软件与程序的区别,《战国策-秦策》中的那句话,王不如远交而近攻, ...

10条建议让你创建更好的jQuery插件

前言:在开发过很多 jquery 插件以后,我慢慢的摸索出了一套开发jquery插件比较标准的结构和模式。这样我就可以 ...


本网站部分内容来自互联网,版权归原作者所有,文章内容仅代表原作者个人观点。如有侵权请联系我们删除 电子邮件 itjcku@foxmail.com