C++程序员语言是如何评价GO语言的(模块化和面向对象

原标题:C++程序员是如何评价GO语言的(模块化和面向对象)

这是关于评论GO语言的第二部分,第一部分:,第三部分会在不日后在CSDN公众号(ID:csdnnews)发布。

在第一部分里面就GO语言的简单功能(特征)做了论述,如常用语法,基本类型等。本文将主要提及GO所支持的package(包)和面向对象。在这之前呢,还是建议读者阅读一下此书,照旧,欢迎各方高人点评和纠错。

总的来说,我发现GO语言面向对象的语法有点乱,一致性差、不明显,所以对于大多数使用场合,个人更倾向于C++明显的继承层次结构。

在这个部分的文章里面故意不提及系统构建,分发或者配置等内容。

Go代码是以软件包的形式组织的,Java也有包的概念,二者很像,跟C++命名空间也有点类似。 在源文件的开头声明包的名称:

当需要用到某个包时,用import方式导入:

import ( //告诉Go编译器这个程序需要使用 foo、moo 包(的函数,或其他元素)

包名称应与文件的目录名称匹配。 这是import语句找到对应包的关键。一个目录可允许有多个文件,这些文件都是同一个包的一部分。

package main不受以上规则约束。由于其唯一性,所以对应的目录不需要命名为main。

在Go语言中可以像C一样声明一个结构体:

我习惯使用var关键字演示变量的实际类型,也可能会选择较短的表达式 := 。

请注意,我们可以将其创建为一个值或一个指针(使用内置的new()函数),与C或C ++不同,Go中的结构体所占的实际内存并不能确定是在堆还是栈上。 具体由编译器决定,一般是根据内存是否需要延续功能调用来分配。

以前,我们已经看到内置的make()函数用于实例化slices(切片)和maps(集合)。 make()仅适用于那些内置类型。 对于自定义类型,可以使用new()函数。 我发现这个区别有点混乱,但是我一般不喜欢使用语言本身就可以实现的类型区别。 我喜欢C++标准库如何在C++中实现方式,当往库里面添加内容时,语言本身几乎没有什么特别的支持。

Go类型通常具有“构造函数”(而不是方法),应该调用该函数来正确实例化该类型,但是我认为没有办法强制执行正确的初始化,就像C++或Java中的默认构造函数。 例如:

可以匿名地将一个结构体“嵌入”到其他结构体中,如下所示:

这感觉有点像C ++和Java中的继承,例如,可以这样:

Go语言中的结构体可以有Methods(与结构相关联的函数),这点和C/Java语言的classes(类)很像 , 但在语法方面略有不同。 Method在结构体外被声明,并且通过在函数名之前指定“receiver”来进行调用。 例如,它声明(并实现)Thing结构体的DoSomething方法:

还有需要注意的一点,由于GO没有内置如“self”或“this”的实体名,故必须为receiver指定一个名称。这感觉有点相互矛盾。

可以使用指针替代,而且如果要更改关于struct实例的任何内容,指针是不二选择:

如果需要保持代码的一致性,最好给method receivers指定为指针类型。

跟C++/Java不同,这允许检查实例是否为nil(Go为null或nullptr),使其可以在null实例上调用方法。 这让我想起Objective-C如何在nil实例上调用方法而没有崩溃,甚至返回一个nil/zero值。 我发现Objective-C没有这一机制,更让我沮丧的是,Go允许这样做,但没有一定的一致性。

与C++或Java不同,GO甚至可以将methods与非struct(非类)类型相关联。 例如:

没有赋值或比较运算符重载

在C++里面,可将=、 !=、 <、>、等运算符重载,所以可以使用这些常规的运算符,使代码看起来更整洁:

在Go语言中不能这么使用, 只有部分内建类型是可比较的,如数字类型,字符串,指针或通道,或由这些类型组成的结构体或数组。当处理接口时这会是一个麻烦,我们稍后会看到。

符号可见性: 大写或小写字母

以大写字母开头的符号 (类型、函数、变量) 可从包外部获得。结构方法和以大写字母开头的成员变量可从结构外部获得。否则,它们就是私有的包或结构。例如:

感觉这有点奇怪。相对而言, c++和Java中明确用public和private关键字声明显得更加友善。

如果两个Go类型满足一个接口,那它们都具有该接口的方法, 这与Java接口类似。 Go接口也有点像C ++中的一个完全抽象类(只有纯虚方法),跟C ++ Concept(概念)也很像(自C ++ 17)。

然后,就可以使用接口类型而不是特定的 “实际” 类型:

请注意,这里使用的是Shape, 而不是使用Shape(指向Shape的指针), 即使是从 Circle(指向circle)转换。 “接口值”似乎是隐式指针,这似乎是不必要的混淆。 如果指向接口的指针只是具有与这些“接口值”相同的行为,即使语言禁止使用指针的接口类型, 它也会更加一致。

但是,没有明确声明类型应实现接口。

通过这种方式, 接口就像C++的概念, 虽然C++概念是纯编译时功能, 用于通用 (模板) 代码。您的类可以符合 c++ 概念,而无需具体声明。因此, 与 go 接口一样, 如果必须, 您可以使用现有类型而不更改它。

编译器仍需检查类型是否兼容, 但可能是检查类型的方法链表, 而不是检查类层次结构或已实现接口的链表。例如:

像 c++ 的dynamic_cast一样,GO 也可以在运行时检查。例如,可以检查一个接口值是否引用一个同时满足另一个接口的实例:

或者,可以检查接口值是否特指某种具体类型。例如:

接口方法也类似于 c++ 虚方法 (或java 方法), 接口变量也类似于多态基类的实例。为了通过接口变量实际调用接口的方法, 程序需要在运行时检查其实际类型, 并调用该类型的特定方法。也许,与 c++ 一样,编译器有时可以优化掉这种间接寻址。

这显然不如直接调用 c++ 模板中的模板化类型在编译时标识的方法那样有效。但它显然是简单得多。

接口值有时可以比较, 但这似乎是一个危险的业务。接口值为:

  • 类型相同,只有一个为nil,不相等。

  • 类型相同,可比较,并且它们的值一样,则相等。

但是,如果类型是相同的,但这些类型是不可比较的, 将导致Go在运行时抛出异常 “panic”。(译者注:panic 是用来表示非常严重的不可恢复的错误的。在Go语言中这是一个内置函数,接收一个interface{}类型的值(也就是任何值了)作为参数。panic的作用就像我们平常接触C++的异常)

在C ++中,如果你愿意,可以显式声明一个类应符合该概念,或者你可以从一个基类中显示的派生出来,而在Java中,必须使用“implements”关键字。由于GO语言没有此机制,因此需要习惯。我想要这些声明来记录我的架构,根据他们的一般目的明确地显示我的“具体”类的预期,而不是仅仅用一些其他代码来表达它们。没有这个感觉很脆弱。

该书建议将这个笨拙的代码放在某处,以检查一个类型是否真正实现了一个接口。注意_(下划线)的使用意味着我们不需要为结果保留一个命名变量。

如果类型不满足接口,转换是不可能的,编译器应该报错。作为最初级测试,我认为这是明智之举。特别是如果您的包提供的类型,不是真正使用的包本身。对于我来说, 这是一个很糟糕的替代品,它使用特定的语言构造对类型本身进行明显的编译时检查。

GO不具有继承层次结构的概念, 但您可以在一个接口中 “嵌入”另 一个接口, 以指示满足一个接口的类也满足另一个接口。例如:

为了满足Shape接口,任何类型也必须满足Drawable和Positionable接口。 因此,任何满足Shape接口的类型都可以与Drawable或Positionable接口关联的方法使用。 这有点像一个java接口扩展另一个接口。

在结构体中嵌入一个满足接口的结构体

我们早些时候就看到了如何将一个结构嵌入另一个匿名结构体中。如果包含的struct实现了一个接口, 则包含的struct也可以实现该接口, 而不需要手动实现的转发方法。例如:

我实际上非常喜欢匿名地包含结构体的(接口)结构影响父结构的接口,即使是Go的异样接口系统,尽管我希望语法对于发生的事情更加明显。在C++中有类似的东西可能很好。封装而不是继承(和Decorator模式)是一种非常高效的技术,C ++通常会尝试以多种方式进行操作,而不会对最好的方式有所了解,尽管这本身就会成为复杂性的来源。但是在C++(和Java)中,你现在必须手动编码大量的转发方法来实现此目的,您仍然需要继承某种东西,以告知支持封装接口的类型系统。

}

      整个知识体系围绕逻辑结构来的话,是面向过程,围绕对象来的话,是面向对象。所以一个知识体系可以从字段,函数,结构体入手,再到详细编码的逻辑结构,也就是面向过程进行加深。然后是指针,异常机制,IO,并发等。有了基本架构之后才是网络,后台等高级特性。

      需要注意的是go语言的设计基本上遵循尽量简化的原则进行,就是能简化就简化,当然,也有部分奇怪的没有简化的,但是这也是因为有其他的考量原因。

1.数据操作。包括基本数据类型的定义以及操作,运算,切片等。注意指针。

2.字段在结构体中可以是匿名字段。

3.array,map,slice是高级结构体。array是数组,而slice针对数组进行的切片处理。map是映射。使用range遍历。

1.结构体的定义。在go中类是结构体与函数叠加而成。而结构体就是算法与结构中的“结构”。

2.type用于重定义数据,定义结构体,接口。

3.go更加接近理论,所以在go中类,方法,变量,被叫做结构体,函数,字段。.

1.函数的定义。在go中都是函数,而属于结构体的函数可以称为方法。

字段和返回字段可以简化。如input1,input2 type。这其实就是如果当前没有就往后面找。

1.if参照了for,可以使用;分号隔开,前面的是变量声明。

3.for格式如果省略了分号,那么就相当于while。for range可以用于读取slice和map的数据。

1.string,slice,map都是基于指针的机制了,可以直接传递,不需要再取地址传指针操作。但是注意slice的长度发生变化的话,仍需取地址传指针。

2.结构体指针函数的使用需要注意。

1.go中,异常处理使用panic(),recover(),defer联合使用。panic抛出异常中断,如果想要回复,可以在defer中使用recover恢复。但是go中,尽量少用异常处理。

1.go中使用make()创建切片,映射,程道。返回对象,而new()返回的是指针。

2.chan分为有缓冲和无缓冲两种。

3.chan作为线程件通信的IO通道。

1.并发里面主要是多线程以及常用的辅助类等。

2.并发的内容一般包含:

(1)线程的初始化。线程的实现是go xxx,这个过程叫做gorutine。

(2)线程的通信。通过channel进行通信。注意,这里channel本身是具有锁功能的,往往作为最简单常用的锁进行使用

(3)线程对于资源的操作。这里主要是同步异步,阻塞和非阻塞等概念。

        同步异步的关键在于互斥,而阻塞和非阻塞关键在于锁。但是两者其实很接近。

        所以往往出现的是互斥锁。这里常用的是sync.Mutext.Lock()实现互斥锁。使用lock.Lock()实现锁。runtime模块往往用于运行时候的一些操作,帮助线程实现让出时间片,线程退出等操作。atomic模块是原子操作。其他的一些类和函数是基于这些概念进行的扩展。

当一个函数调用前有关键字 defer 时, 那么这个函数的执行会推迟到包含这个 defer 语句的函数即将返回前才执行

defer 调用的函数参数的值在 defer 定义时就确定了, 而 defer 函数内部所使用的变量的值需要在这个函数运行时才确定。defer 函数调用的执行时机是外层函数设置返回值之后, 并且在即将返回之前

对数据进行上锁,防止数据被其它线程更改。Mutex是一个互斥锁,可以作为struct的一部分,这样这个struct就会防止被多线程更改数据。

注意:执行加锁后,在执行完操作后记得解锁,不然会有错误。常常defer关键字与解锁共用。


}

原标题:Go语言入门教程之为什么一定要学Go语言?

了解Go语言的应该都知道,Go语言是谷歌2009发布的第二款开源编程语言。Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。

今天容大教育和大家讨论一下为什么要选择学习Go语言呢?与其他语言的应用相比,Go有什么优点呢?下面我们一起看一下Go语言入门教程:

1、Go语言入门学习曲线

它包含了类C语法、GC内置和工程工具。这一点非常重要,因为Go语言容易学习,所以一个普通的大学生花一个星期就能写出来可以上手的、高性能的应用。在国内大家都追求快,这也是为什么国内Go流行的原因之一。

Go拥有接近C的运行效率和接近PHP的开发效率,这就很有利的支撑了上面大家追求快速的需求。

3、出身名门、血统纯正

之所以说Go语言出身名门,是因为我们知道Go语言出自Google公司,这个公司在业界的知名度和实力自然不用多说。Google公司聚集了一批牛人,在各种编程语言称雄争霸的局面下推出新的编程语言,自然有它的战略考虑。而且从Go语言的发展态势来看,Google对它这个新的宠儿还是很看重的,Go自然有一个良好的发展前途。我们看看Go语言的主要创造者,血统纯正这点就可见端倪了。

4、自由高效:组合的思想、无侵入式的接口

Go语言可以说是开发效率和运行效率二者的完美融合,天生的并发编程支持。Go语言支持当前所有的编程范式,包括过程式编程、面向对象编程以及函数式编程。程序员们可以各取所需、自由组合、想怎么玩就怎么玩。

这包括互联网应用、系统编程和网络编程。Go里面的标准库基本上已经是非常稳定了,特别是我这里提到的三个,网络层、系统层的库非常实用。

6、部署方便:二进制文件、Copy部署

我相信这一点是很多人选择Go的最大理由,因为部署太方便了,所以现在也有很多人用Go开发运维程序。

它包含了降低心智的并发和简易的数据同步,我觉得这是Go最大的特色。之所以写正确的并发、容错和可扩展的程序如此之难,是因为我们用了错误的工具和错误的抽象,Go可以说这一块做的相当简单。

Go拥有强大的编译检查、严格的编码规范和完整的软件生命周期工具,具有很强的稳定性,稳定压倒一切。那么为什么Go相比于其他程序会更稳定呢?这是因为Go提供了软件生命周期(开发、测试、部署、维护等等)的各个环节的工具,如go tool、gofmt、go test。

Go语言适合用来做什么?

服务器编程:以前你如果使用C或者C++做的那些事情,用Go来做很合适,例如处理日志、数据打包、虚拟机处理、文件系统等。

分布式系统:数据库代理器等。

网络编程:这一块目前应用最广,包括Web应用、API应用、下载应用、内存数据库。

云平台:google开发的groupcache,couchbase的部分组建云平台,目前国外很多云平台在采用Go开发,CloudFoundy的部分组建,前VMare的技术总监自己出来搞的apcera云平台。

nsq:bitly开源的消息队列系统,性能非常高,目前他们每天处理数十亿条的消息

docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建

packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者

skynet:分布式调度框架

tsuru:开源的PAAS平台,和SAE实现的功能一模一样

god:类似redis的缓存系统,但是支持分布式和扩展性

gor:网络流量抓包和重放工具

哪些大型互联网公司在用go语言?

这个不用多做介绍,作为开发Go语言的公司,当仁不让。Google基于Go有很多优秀的项目,比如:/google/ 查看更多Google的Go开源项目。

Facebook也在用,为此他们还专门在Github上建立了一个开源组织facebookgo,大家可以通过 /此外,小米互娱、小米商城、小米视频、小米生态链等团队都在使用Golang。

容大教育IT培训机构,能够为你提供良好的技术学习,能够更好地了解每个学习者的需求,根据每个学习者特定的需求为其配置最合适的资产组合,无疑更加符合学习者的需求。

}

我要回帖

更多关于 程序员语言 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信