我为什么喜欢Go语言

来源:http://www.cnblogs.com/AllenDang/archive/2012/03/03/2378534.html

 

从2000年至今,也写了11年代码了,期间用过VB、Delphi、C#、C++、Ruby、Python,一直在寻找一门符合自己心意和理念的语言。我很在意写代码时的手感和执行的效率,所以在Go出现之前一直没有找到。在熟悉Go之后,我虽没有停下脚步,也去体验了D语言,但几乎立即就放弃了,它的设计还是太复杂。

就说说Go吧。它的好其实也就两个字——简洁!

 

看很多朋友的留言都觉得这些“少个括号、少个分号”之类的东西没什么意义,真的吗?问题是,既然可以没有,为什么非得有?既然能够少打一个字符,为什么多打了还挺开心?还觉得天经地义?这里简单一点,那里简单一点,总的来说是不是就简单了很多?这里的设计简洁一点,那里简洁一点,是否整体就是紧凑高效?

很多东西,要整体去体会,才能感觉到真正的强大。没有前面这些语法上的各种“看起来没什么用”的支持,怎么能做到后面提到的那些设计上的简洁?

 

我坚信,少就是多,简单就是强大,不能减一分的设计才是真正的好设计!

简洁的变量声明和赋值

拿最简单的声明变量和赋值来看,下面这一句完成了声明类型到赋值,最后还有那个常见的分号作为语句的结束。

var i int = 10;

这个一点都不简洁对吧?为什么非要有“var”?为什么不能自己推导变量类型?为什么结尾非要加上分号?这三个问题,我相信Go语言的设计者也问过,并且都针对性的给了改进。重新来过。

i := 10

怎么样?“:=”是声明并推导类型的语法糖,结尾的分号也省了,因为这里我换行了,编译器明白的。

还可以一次性声明并赋值多个变量。

i, j, k := 1, 2, 3

不同的类型也可以。

i, j, k := 1, 1.0, “hello”

如果要声明一堆变量,但暂时不赋值呢?可以这样。

var (

    i, j int
    s string
u, v, s = 2.0, 3.0, "bar"

)

Go的设计者甚至觉得多打几个“var”都不应该!

 

简洁的if

有点意思了对吧?我学习一门新语言的时候,第一眼看变量类型和声明,第二眼就会去看逻辑控制的语法。现在来看看都有些什么?

if i > 10 {

    println(“Greater then 10”)

}

稀松平常啊,难道一个简单的if还能更简单?恩,的确是的。首先if后面的条件判断没有人逼你再加上括号了,仅仅是少了两次按键嘛,还有呢?还有!下面这个应该是很常见的if使用场景。

result := SomeMethod()

if result > 0 {

}

很多时候result这个变量其实仅仅用于条件判断,完全可以在if之后就扔掉,所以Go有了这么个写法。

if result := SomeMethod(); result > 0 {

}

这个表达式太常用了,真是谁写谁知道,每次我写着一行都会心里一爽。来看看纠结一点的if段。

if a {

} else if b {

} else if c {

} else {

}

这种写法是可以的,但不是Go推荐的,理由是可以更简洁。比如强悍的switch。

 

强悍的switch

这是很大家熟知的switch用法,注意,没有break哦!Go里面case之间不会“下穿”。

switch tag {
default: 
        s3()
case 0, 1, 2, 3:
        s1()
case 4, 5, 6, 7: 
        s2()
}
神奇一点的switch,嘿嘿,与if异曲同工之妙。
switch x := f(); {  // missing switch expression means "true"
case x < 0: return -x
default: return x
}

还有这个,有了这个更加明确的写法,你真的还会if…else if…else if…else…吗?

switch {
case x < y: f1()
case x < z: f2()
case x == 4: f3()
}

条件判断舒服了,循环呢?

 

孤单的for

其实我一直不太明白,为什么一门语言里面要提供多个循环语法呢?for、while、do…while…都是不可替代的?用哪一个呢?似乎都是看个人爱好吧?可能大家随便就可以举个例子出来证明这三个东西存在的必要和细微的差别,但对于我来说,做同一件事情如果有多种方法其实就是设计上的冗余,会对使用者造成或多或少的困扰。来看看Go的循环吧。

for i := 0; i < 10; i++ {

}

for a < b {

}

for {

}

看吧,一个for就搞定所有情况了。来看一个常用的遍历集合,一把来说会写成这样。

count := len(someArray)

for i := 0; i < count; i++ {

    println(someArray[i])

}

简化这个,Go给出了一个关键字“range”,先看用法。

for i, value := range someArray {

    // i 是整型,代表下标

    // value就是数组内值的类型

}

range不单单可以用于数组,实际上它可以用于任何集合,比如map。

m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
for i, s := range a {
// type of i is int
// type of s is string
}

这里只是提到了几点最基本的语法场景,Go里面还有很多!

 

函数可以返回多个值

其实能够在一行多重赋值的语言挺多的,但一个函数能返回多个值的就很少了,比如在C#里面如果要返回两个int,通常会这么干。

public class TwoInts

{

    public int A;

    public int B;

}

public class Foo

{

    public TwoInts ReturnTwoInt();

}

然后就可以 TwoInts ti = foo.CalcTwoInt() 觉得悲催吗?也许你都麻木了对吗?很多语言都是这么设计的。函数只能返回一个值最大的问题是会导致出现很多没必要的数据结构。上面就体现了这个冗余,当然,你说可以用out关键字让函数返回,但这个语法用起来就不是那么安全了。而这个问题在Go里面解决起来太容易了,因为Go的函数可以返回多个值!

func returnTwoInt() (int, int) {

}

a, b := returnTwoInt()

我对Go的好感就是从这里萌芽的,这让我的库里面从此少了很多数据结构!这无形中就能降低设计的复杂度。

 

函数内部声明的对象指针可以安全的返回

func ReturnPointer() *Object1 {

    obj := new Object1()

    obj.A = “hello”

    return obj

}

Go的垃圾回收器会处理好这种情况的,放心啦!

 

异常处理?defer是啥?能吃吗?

为什么异常处理那么复杂?多少人可以安全的实现下面这个逻辑?以下是伪代码。

File f = File.Read(“c:\\text.txt”)

f.Write(xxx)

f.Close()

我相信,有经验的码农们脑子里面瞬间出现了各种版本的try…catch…finally…,还有各种各样的书写规范,比如“catch”里面的逻辑不能在抛异常之类的东西。其实想想,我们的要求很简单,打开一个文件,然后保证它在最后被关闭。仅此而已,为什么做这么简单的一件事情非要那么复杂?看看人家Go是怎么做的!

func SaveSomething() {

    if f, err := os.Open(“c:\\text.txt”); err == nil {

        //各种读写

        defer f.Close()

    }

}

凡是加了defer的函数,都会在当前函数(这里就是SaveSomething)执行完毕之后执行。就算“//各种读写”时发生异常f.Close也会坚定的在SaveSomething退出时被执行。有了这个,释放点资源,关闭个把句柄这种小事再也无足挂齿!

 

接口再也不用“实现”了

从我接触OO思想一来,凡是有接口的语言,都以不同的方式要求类“实现”接口,这样的方式我一直都认为是天经地义的,直到我遇见了Go。

type Speaker interface {

    Say()

}

上面定义了一个接口,只有一个方法,Say,不需要参数,也没有返回值。Go里面,任何拥有某个接口所定义所有方法的东西,都默认实现了该接口。这是一句拥有太多内涵的话,足矣对设计思路产生重大的影响。比如下面这个方法,它接受一个类型为Speaker的参数。

func SaySomething(s Speaker) {

    s.Say()

}

那么所有拥有Say()方法的东西都可以往里扔。

在Go的世界里,所有的东西都默认实现了interface{}这个接口。有了这个概念,即使没有泛型也能有效的降低设计复杂度。

 

多线程还能更简单点吗?

要写多线程,你要懂Thread,懂各种锁,懂各种信号量。在各类系统里面,“异步”逻辑通常代表“困难”。这是Go最强劲的部分,你见过比下面这个还简单的异步代码吗(以下代码摘自Go的官方范例)?

func IsReady(what string, minutes int64) { 
    time.Sleep(minutes * 60*1e9); 
    fmt.Println(what, "is ready") 

go IsReady("tea", 6); 
go IsReady("coffee", 2); 
fmt.Println("I'm waiting....");

执行的结果是,打印: 
I'm waiting.... (right away) 
coffee is ready (2 min later) 
tea is ready (6 min later)

Go语言内置了“go”这个语法,任何go的方法,都将会被异步执行。那异步方法之前传递消息呢?用channel呗。意如其名,就是一个管道,一个往里写,另外一个等着读。

ch := make(chan int) //创建一个只能传递整型的管道

func pump(ch chan int) { 
    for i := 0; ; i++ { ch <- i } //往管道里写值 
}

func suck(ch chan int) { 
    for { fmt.Println(<-ch) } //这里会等着直到有从管道里面出来 
}

go pump(ch) //异步执行pump

go suck(ch) //异步执行suck

嘿嘿,然后你就看到控制台上输出了一堆数字。

 

这次就写到这儿吧,对不住Go里面其他的好东西了,哥饿了,就不一一出场亮相了,抱歉抱歉!鞠躬!下台!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netflix 官方技术博客:个性化分发与推荐,走在前列的 Netflix 是怎么做的?

来源&#xff1a;36氪概要&#xff1a;对于个性化分发与推荐&#xff0c;Netflix都是一个走在前面的公司。其首页的个性化推荐策略不断被后来者所模仿。对于个性化分发与推荐&#xff0c;Netflix都是一个走在前面的公司。其首页的个性化推荐策略不断被后来者所模仿。近日&#…

android主要文件的作用是什么,androidmanifest.xml文件的作用是什么

androidmanifest.xml文件的作用&#xff1a;1、是每个android程序中必须的文件&#xff0c;它位于整个项目的根目录&#xff1b;2、配置程序运行所必要的组件&#xff0c;权限&#xff0c;以及一些相关信息&#xff1b;3、是整个应用的入口&#xff0c;所以有助于更加深入的理解…

盘点丨2017年亚洲新晋18家独角兽公司

来源&#xff1a;网易科技概要&#xff1a;在投资领域&#xff0c;当一个创业公司估值达到10亿美元时&#xff0c;人们就称它加入了独角兽俱乐部。在投资领域&#xff0c;当一个创业公司估值达到10亿美元时&#xff0c;人们就称它加入了独角兽俱乐部。据国外媒体Tech in Asia报…

LiteIDE 编写Go的单元测试

第一步&#xff1a;新建一个 package "even" 第二步&#xff1a;编写代码 // even project even.go package evenfunc Even(i int)bool{return i%20 }func odd(i int)bool{return i%21 }第三步&#xff1a;在包 even 下新建测试文件 even_test.go第四步&#xff1a;…

揭秘Facebook SLAM技术,如何为人们生活增添奇幻的艺术色彩?

来源&#xff1a;将门创投概要&#xff1a;随着现代智能手机技术的发展&#xff0c;几乎所有的手机都配备了摄像头、陀螺仪和加速度传感器&#xff0c;硬件的进步帮助SLAM技术得到更广泛的传播和应用。 在过去的一年里&#xff0c;虚拟现实技术(Virtual Reality&#xff0c;简称…

android系统签名app自动更新,【Android 进阶】Apk 使用系统签名

刚入职的时候&#xff0c;固件中 app 需要在源码中编译&#xff0c;不是很理解&#xff0c;为什么不使用 IDE 编译&#xff0c;然后 copy 到 /system/app/*,咨询导师&#xff0c;得到反馈 app 需要使用系统的权限 在 AndroidManifest.xml 中声明了系统全下申明了系统权限androi…

数独游戏破解

游戏规则&#xff1a; 1、每行都是 1~9 2、没列都是 1~9 3、每块都是 1~9 解答思路&#xff1a; 从坐标 [0][0] 开始&#xff0c;算出其允许填入的数字集合&#xff08;每行允许数字集合、每列允许数字集合 和 每块允许数字集合 的交集&#xff09;。 从左到右&#xff0c…

人工智能能否在对抗虚假新闻战争中完胜?

来源&#xff1a;亿欧概要&#xff1a;2017年&#xff0c;误导性和恶意的虚假在线内容是如此丰富多产&#xff0c;以至于人类无法让自己解脱困境。反而&#xff0c;这越发看来机器将不得不拯救我们。这可能是互联网历史上的第一个虚假新闻&#xff1a;1984年&#xff0c;有人在…

android gpu 视频编码,android – 编码器崩溃对Adreno GPU编码从Surface

我一直在努力解决这个问题超过一个星期&#xff0c;很可能是一个错误的Qualcomm GPU /硬件视频编码器。因为我们被迫发布应用程序&#xff0c;并且他们的开发人员论坛没有提供任何反馈&#xff0c;我也在这里发布它&#xff0c;希望有人能够提供一些线索&#xff0c;或更好&…

穷举法破解集合小游戏~

游戏网站&#xff1a;http://www.setgame.com/puzzle/set.htm 游戏规则&#xff1a; 1、三种颜色&#xff08;红、绿、紫&#xff09; 2、三种外形&#xff08;方形、椭圆形、花形&#xff09; 3、三种背景阴影&#xff08;实心、点、轮廓&#xff09; 4、三种个数&#x…

AI时代数据之争,我们需要什么样的“数据权”?

来源&#xff1a; 腾讯研究院作者&#xff1a;田小军 腾讯研究院高级研究员1、未来是AI云端的数据竞争时代“兵无常势&#xff0c;水无常形”&#xff0c;今年11月4日&#xff0c;我国《反不正当竞争法》历时24年后首次修订&#xff0c;专设“互联网专条”用以规制互联网行业竞…

android点击通知后消失,通知栏点击后消失解决方法

通知栏点击后消失怎么使通知栏点击后消失啊&#xff1f;以下为我的代码&#xff0c;能实现将信息放入通知栏&#xff0c;但是点击后不消除。。。private void showNotification(String temp) {// 创建一个NotificationManager的引用NotificationManager notificationManager (…

Struts2 的Action 命名重复检测

原因&#xff1a;在实际项目中发现 <action /> 的 name 重复时候&#xff0c;Struts2 并不会报错而是随意找一个去执行&#xff01; 为了避免重复的情况发生&#xff0c;特地写了一个检测的程序&#xff1a; package barcode;import java.io.IOException; import java.i…

预测性智能的力量:AI 和机器学习将如何改变美国政府决策?

来源&#xff1a;36Kr在每个联邦机构中&#xff0c;重要的见解都隐藏在这些年来收集的大量数据集中。 但是由于美国联邦政府数据科学家的匮乏&#xff0c;如果真的要这么做的话&#xff0c;那么从这些数据中提取价值是非常耗时的。 然而&#xff0c;随着数据科学&#xff0c;人…

android 源码分析notification,# Notification 源码分析

引言notification.jpgNotification 在v7版本下从4.0后增加了Media Style. 今天我们分析下Notification在v7版本的源码。有助于我们针对不同版本的Notification做出合适样式选择。Notification使用流程现在我们使用Notification基本都是如下步骤:NotificationCompat.Builder bui…

广州签发全国首张微信身份证,AI成主要证明技术

来源&#xff1a;人工智能学家AItists概要&#xff1a;12月25日&#xff0c;广州市公安局南沙区分局、腾讯、建设银行等10余家单位发起的“微警云联盟”在广州南沙成立&#xff0c;现场签发了全国首张微信身份证“网证”。12月25日&#xff0c;广州市公安局南沙区分局、腾讯、建…

android底层设置相机帧率,Android Camera previewFrame 提高 fps

/*** http://my.oschina.net/lifj/blog/705104**/在做Camera预览的时候&#xff0c;通过PreviewFrame()方法获取数据&#xff0c;但是发现fps很低&#xff0c;一直在10~12fps徘徊。当然&#xff0c;有人推荐使用setPreviewCallbackWithBuffer。试了一下&#xff0c;fps没有明显…

android 视频做背景图片,视频后面怎么加背景图片?安卓手机给视频添加背景图片的方法...

狸窝是帮助用户解决问题 提供教程解决方案 在这个过程中有使用我们自己开发的软件 也有网上找的工具 只要帮助用户解决问题就好&#xff01;同意则往下继续了解学习 ...注意此教程方案是:『安卓手机端教程方案』。很多手机视频分享平台对视频参数都会有要求&#xff0c;手机上大…

MySQL中information_schema

来源&#xff1a;http://hi.baidu.com/starsw001/item/d151bd591cfb7f01e7c4a557 大家在安装或使用MYSQL时&#xff0c;会发现除了自己安装的数据库以外&#xff0c;还有一个information_schema数据库。 information_schema数据库是做什么用的呢&#xff0c;使用WordPress博客…

量子计算远没到可收割的时候

来源&#xff1a;风云之声概要&#xff1a;我们重视量子计算&#xff0c;是因为它的潜力&#xff0c;而不是它的现状。它确实有革命性的潜力&#xff0c;只是还需要艰苦的努力&#xff0c;绝不是一蹴而就的&#xff0c;更不是已经处在商业盈利的边缘&#xff0c;等着大家一哄而…