1、 Go语言作为服务器编程语言,很适合处理日志、数据打包、虚拟机处理、文件系统、分布式系统、数据库代理等;网络编程方并卖埋面。Go语言广泛应用于Web应用、API应用、下载应用等;除此之外,Go语言还可用于内存数据库和云平台领域,目前国外很多云平台都是采用Go开发。
2、 其实Go语言主要用作服务器端开发。其定位是用来开发"大型软件"的,适合于很多程序员一起开发大型软件,并且开发周期长,支持云计算的网络服务。Go语言能够让程序员快速开发,并且在软件不断的增长过程中,它能让程序员更容易地进行维护和修改。它融合了传统编译型语言的高效性和脚配做本语言的易用性和富于表达性。
3、 Go语言成功案例。Nsq:Nsq是由Go语言开发的高性能、高可用消息队列系统,性能非常高,每天能处理数十亿条的消息;
4、 Docker:基于lxc的一个虚拟打包工具,能够实现PAAS平台的组建。
5、 Packer:用来生成不同平台的镜像文件,例如VM、vbox、AWS等,作者是vagrant的作者
6、 Skynet:分布式调度框架。
7、 Doozer:分布式同步工具,类似ZooKeeper。
8、 Heka:mazila开源的日志处理系统。
9、 Cbfs:couchbase开源的分布式文件系统。
10、 Tsuru:开源的PAAS平台,和SAE实现的功能一模一样。
11、 Groupcache:memcahe作者写的用于Google下载系统的缓存系统。
12、 God:类似redis的缓存系统,但是支持分布式和扩展性。
13、 Gor:网络流量抓包和重放工具。
以上的就是关于go语言能做什么的内容介绍了。
在Go中,error是一种内建的数据类型。在Go中被定义为一个接口,定义如下:
由此可知,该接口只有一个返回字符串的Error函数,所有的类型只要实现了该函数,就创建了一个错误类型。
创建error的方式包括errors.New、fmt.Errorf、自定义实现了error接口的类型等。
2.1 通过errors.New方法创建
通过该方法创建的错误一般是可预知的错误。简单来说就是调用者通过该错误信息就能明确的知道哪里出错了,而不需要再额外的添加其他上下文信息,我们在下面的示例中详细说明。
我们看New方法的实现可知,实际上是返回了一个errorString结构体,该结构体包含了一个字符串属性,并实现亩冲了Error方法。代码如下:
error.New使用场景1 :
通过errors.New函数创建局部变量或匿名变量,且不在调用函数中进行值或类型判断的处理,只打印或记录错误日志的场景。
使用示例1 :
以下代码节选自源码/src/net/http/request.go中解析PostForm的部分。 当请求中的Body为nil时,返回的错误信息是"missing form body"。该信息已明确的说明错误是因为请求体为空造成的,所以不需要再额外的添加其他上下文信息。
使用示例2
以下代码选择源码/src/net/http/transport.go的部分,当请求体中的url地址为nil返回的错误:迅信歼"http: nil Request.URL" ,说明是请求中的URL字段为nil。以及当Header为nil返回的错误:"http:nil Request.Header",说明请求体中的Header字段为nil。
error.New使用场景2 :
将errors.New创建的错误赋值给一个全局的变量,我们称该变量为哨兵错误,该哨兵错误变量可以在被处理的时候使用 == 或 errors.Is来进行值的比较。
使用示例 : 在源码/src/io/io.go中定义的代表文件末尾的哨兵错误变量EOF。
在beego项目中,beego/core/utils/file.go文件中有这样的应用,当读取文件时,遇到的错误不是文件末尾的错误则直接返回,如果遇到的是文件末尾的错误,则中断for循环,说明文坦扒件已经读完文件中的所有内容了。如下:
2.2 通过fmt.Errorf方法创建
使用场景1:不带%w占位符 :
在创建错误的时候,不能通过errors.New创建的字符串信息来描述错误,而需要通过占位符添加更多的上下文信息,即动态信息。
使用示例:不带%w占位符 :
以下示例节选自gorm/schema/relationship.go的部分代码,当外键不合法时,通过fmt.Errorf("invalid foreign key:%s", foreignKey)返回带具体外键的错误。因为外键值是在运行时才能确定的。代码如下:
使用场景2:带%w的占位符 :
在有些场景下,调用者需要知道原始错误信息,一般会通过errors.Is函数进行判断该错误链中是否包含某种特定类型的原始错误值。
使用%w占位符创建的错误信息,其实会形成一个错误链。其用法如下:
我们再来看下源代码:
通过源码可知,如果fmt.Errorf中包含%w占位符,创建的是一个wrapError结构体类型的值。我们再来看下wrapError结构体的定义:
字段err就是原始错误,msg是经过格式化之后的错误信息。
使用示例:带%w的占位符 :
假设我们有一个从数据库查询合同的函数,当从数据库中查询到记录为空时,会返回一个sql.ErrNoRows错误,我们用%w占位符来wrap该错误,并返回给调用者。
好了,现在GetContract的调用者可以知道原始的错误信息了。在调用者逻辑中我们可以使用errors.Is来判断err中是否包含sql.ErrNoRows值了。我们看下调用者的代码:
使用场景 :这个是相对errors.New来说的,errors.New适用于对可预知的错误的定义。而当发生了不可预知的错误时,就需要自定义错误类型了。
使用示例 : 我们以go源码/src/io/fs/fs.go文件中的源码为例,来看下自定义错误类型都需要包含哪些元素。
首先看结构体,有一个error接口类型的Err,这个代表的是错误源,因为根据上面讲解的,在错误层层传递返回给调用者时,我们需要追踪每一层的原始错误信息,所以需要该字段对error进行wrap,形成错误链。另外,有两个字段Op和Path,分别代表是产生该错误的 *** 作和 *** 作的路径。这两个字段就是所谓的未预料到的错误:不确定是针对哪个路径做了什么错误引发了该错误。
我们看下该错误类型在代码中的应用:
应用1 :在go的文件src/embed/embed.go中的代码,当读取某目录时返回的一个PathError类型的错误,代表读取该目录 *** 作时,因为是一个目录,所以不能直接读取文件内容。
应用2 :在go的文件src/embed/embed.go中的代码中,有文件读取的函数,当offset小于0时,返回了一个PathError,代表是在读取该文件的时候,参数不正确。
fs.ErrInvalid的定义如下:
由此可见,PathError中的三个字段值都是不可预知的,都需要在程序运行时才能具体决定的,所以这种场景时,则需要自定义错误类型。
另外,我们还注意到该自定义的类型中有Unwrap函数的实现,该函数主要是为了配合errors.Is和errors.As使用的,因为这两个函数在使用时是将错误链层层解包一一比对的。
根据上一节我们得到,通过%w占位符可以将错误组织成一个错误链。
errors.Is函数就是来判断错误链中有没有和指定的错误值相等的错误,相等于 == *** 作符 。注意,这里是特定的错误值,就像gorm中定义的ErrRecordNotFound这样:
那么我们就可以这样使用errors.Is:
errors.As函数,这个函数是用来检查错误链中的错误是否是特定的类型 。如下代码示例是节选自etcd项目中etcd/server/embed/config_logging.go中的部分代码,代表的是err链中有没有能当做json.SyntaxError类型的错误的,如果能,则将err中的错误值赋值到syntaxError变量上,代码如下:
本文从应用场景的角度讲解了各种创建错误方式的实际应用场景。示例中的代码尽量的选自golang源码或开源项目。 同时,每种的应用场景并非绝对的,需要灵活应用。希望本文对大家在实际使用中能够有所帮助。
1、解压压缩包到go工作目录,如解压到E:\opensource\go\go,解压后的目录结构如下:E:\opensource\go\闭段go├─api├─bin│├─go.exe│├─godoc.exe│└─gofmt.exe├─doc├─include├─lib├─misc├─pkg├─src└─test2、增加环境变量GOROOT,取值为上面的go工作目录3、Path环境变量中添加"%GOROOT%\bin",以便能够直接调用go命令来编译go代码,至此go编译环境就配置好了注:如果不想手动设置系统环境变量,也可下载go启动环境批处理附件,修改goenv.bat文件中的GOROOT值为上面的go工作目录后直接双击该bat文件,go编译环境变量即设置完成。4、测试go编译环境,启动一个cmd窗口,直接输入go,看到下面的提示就是搭建成功了E:\opensource\go\go>goGoisatoolformanagingGosourcecode.Usage:gocommand[arguments]Thecommandsare:buildcompilepackagesanddependenciescleanremoveobjectfilesdocrungodoconpackagesourcesenvprintGoenvironmentinformationfixrungotoolfixonpackagesfmtrungofmtonpackagesourcesgetdownloadandinstallpackagesanddependenciesinstallcompileandinstallpackagesanddependencieslistlistpackagesruncompileandrunGoprogramtesttestpackagestoolrunspecifiedgotoolversionprintGoversionvetrungotoolvetonpackagesUse"gohelp[command]"formoreinformationaboutacommand.Additionalhelptopics:gopathGOPATHenvironmentvariablepackagesdescriptionofpackagelistsremoteremoteimportpathsyntaxtestflagdescriptionoftestingflagstestfuncdescriptionoftestingfunctionsUse"gohelp[topic]"formoreinformationaboutthattopic.5、编译helloworld测试程序,go语言包中test目录带有helloworld.go测试程序,源码见"扮扰附一helloworld.go",直接调用"gobuildhelloworld.go"就生成了"helloworld.exe"可执行程序,运行一下这个程序看到了我们期望的hello,wolrd。E:\opensource\go\轿缺誉go\test>gobuildhelloworld.goE:\opensource\go\go\test>helloworld.exehello,worldE:\opensource\go\go\test>附一helloworld.go//cmpout//Copyright2009TheGoAuthors.Allrightsreserved.//UseofthissourcecodeisgovernedbyaBSD-style//licensethatcanbefoundintheLICENSEfile.//Testthatwecandopage1oftheCbook.packagemainfuncmain(){print("hello,world\n")}欢迎分享,转载请注明来源:内存溢出
评论列表(0条)