我为什么喜欢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 ints 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()