`
JavaCrazyer
  • 浏览: 3009006 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类

Google Go:初级读本

阅读更多

Google最近发布新型的编程语言,Go。它被设计为将现代编程语言的先进 性带入到目前仍由C语言占统治地位的系统层面。然而,这一语言仍在试验阶段并在不断演变。

Go语言的设计者计划设计一门简单、高效、安全和 并发的语言。这门语言简单到甚至不需要有一个符号表来进行词法分析。它可以快速地编译;整个工程的编译时间在秒以下的情况是常事。它具备垃圾回收功能,因 此从内存的角度是安全的。它进行静态类型检查,并且不允许强制类型转换,因而对于类型而言是安全的。同时语言还内建了强大的并发实现机制。

阅读Go

Go的语法传承了与C一样的风格。程序由函数组成,而函数体是一系列的语句序列。一段代码块用花括号括起来。这门语言保留有限的关键字。表达式使用 同样的中缀运算符。语法上并无 太多出奇之处。

Go语言的作者在设计这一语言时坚持一个单一的指导原则:简单明了至上。一些新的语法构件提供了简明地表达一些约定俗成的概 念的方式,相较之下用C表达显得冗长。而其他方面则是针对几十年的使用所呈现出来的一些不合理的语言选择作出了改进。

变量声明

变量是如下声明的:

var sum int // 简单声明 var total int = 42 // 声明并初始化

最值得注意的是,这些声明里的类型跟在变量名的后面。乍一看有点怪,但这更清晰明了。比如,以下面这个C片段来说:

int* a, b;

它并明了,但这里实际的意思是a是一个指针,但b不是。如果要将两者都声明为指针,必须要重复星号。然后在Go语言里,通过如下方式可以将两者都 声明为指针:

var a, b *int

如果一个变量初始化了,编译器通常能推断它的类型,所以程序员不必显式的敲出来:

var label = "name"

然而,在这种情况下var几乎显得是多余了。因此,Go的作者引入了一个新的运算符来 声明和初始化一个新的变量:

name := "Samuel"

条件语句

Go语言当中的条件句与C当中所熟知的if-else构造一样,但条件不需要被打包在括号内。这样可以减少阅读代码时的视觉上的混乱。

括号并不是唯一被移去的视觉干扰。在条件之间可以包括一个简单的语句,所以如下的代码:

result := someFunc(); if result > 0 { /* Do something */ } else { /* Handle error */ }

可以被精简成:

if result := someFunc(); result > 0 { /* Do something */ } else { /* Handle error */ }

然而,在后面这个例子当中,result只在条件块内部有效——而前者 中,它在整个包含它的上下文中都是可存取的。

分支语句

分支语句同样是似曾相识,但也有增强。像条件语句一样,它允许一个简单的语句位于分支的表达式之前。然而,他们相对于在C语言中的分支而言走得更远。

首先,为了让分支跳转更简明,作了两个修改。情况可以是逗号分隔的列表,而fall-throuth也不再是默认的行为。

因此,如下的C代码:

int result; switch (byte) { case 'a': case 'b': { result = 1 break } default: result = 0 }

在Go里就变成了这样:

var result int switch byte { case 'a', 'b': result = 1 default: result = 0 }

第二点,Go的分支跳转可以匹配比整数和字符更多的内容,任何有效的表达式都可以作为跳转语句值。只要它与分支条件的类型是一样的。

因此如下的C代码:

int result = calculate(); if (result < 0) { /* negative */ } else if (result > 0) { /* positive */ } else { /* zero */ }

在Go里可以这样表达:

switch result := calculate(); true { case result < 0: /* negative */ case result > 0: /* positive */ default: /* zero */ }

这些都是公共的约定俗成,比如如果分支值省略了,就是默认为真,所以上面的代码可以这样写:

switch result := calculate(); { case result < 0: /* negative */ case result > 0: /* positive */ default: /* zero */ }

循环

Go只有一个关键字用于引入循环。但它提供了除do-while外C语言当中所有可用的循环方式。

条件

for a > b { /* ... */ }

初始,条件和步进

for i := 0; i < 10; i++ { /* ... */ }

范围

range语句右边的表达式必须是arrayslicestring或者map, 或是指向array的指针,也可以是channel

for i := range "hello" { /* ... */ }

无限循环

for { /* ever */ }

函数

声明函数的语法与C不同。就像变量声明一样,类型是在它们所描述的术语之后声明的。在C语言中:

int add(int a, b) { return a + b }

在Go里面是这样描述的:

func add(a, b int) int { return a + b }

多返回值

在C语言当中常见的做法是保留一个返回值来表示错误(比如,read()返回0),或 者保留返回值来通知状态,并将传递存储结果的内存地址的指针。这容易产生了不安全的编程实践,因此在像Go语言这样有良好管理的语言中是不可行的。

认识到这一问题的影响已超出了函数结果与错误通讯的简单需求的范畴,Go的作者们在语言中内建了函数返回多个值的能力。

作为例子,这个函数将返回整数除法的两个部分:

func divide(a, b int) (int, int) { quotient := a / b remainder := a % b return quotient, remainder }

有了多个返回值,有良好的代码文档会更好——而Go允许你给返回值命名,就像参数一样。你可以对这些返回的变量赋值,就像其它的变量一样。所以我们可以重写divide

func divide(a, b int) (quotient, remainder int) { quotient = a / b remainder = a % b return }

多返回值的出现促进了"comma-ok"的模式。有可能失败的函数可以返回第二个布尔结果来表示成功。作为替代,也可以返回一个错误对象,因此像下面这样的代码也就不见怪了:

if result, ok := moreMagic(); ok { /* Do something with result */ }

匿名函数

有了垃圾收集器意味着为许多不同的特性敞开了大门——其中就包括匿名函数。Go为声明匿名函数提供了简单的语法。像许多动态语言一样,这些函数在它们被定义的范围内创建了词法闭包。

考虑如下的程序:

func makeAdder(x int) (func(int) int) { return func(y int) int { return x + y } } func main() { add5 := makeAdder(5) add36 := makeAdder(36) fmt.Println("The answer:", add5(add36(1))) //=> The answer: 42 }

基本类型

像C语言一样,Go提供了一系列的基本类型,常见的布尔,整数和浮点数类型都具备。它有一个Unicode的字符串类型和数组类型。同时该语言还引入了两 种新的类型:slice map

数组和切片

Go语言当中的数组不是像C语言那样动态的。它们的大小是类型的一部分,在编译时就决定了。数组的索引还是使用的熟悉的C语法(如 a[i]),并且与C一样,索引是由0开始的。编译器提供了内建的功能在编译时求得一个数组的长度 (如len(a))。如果试图超过数组界限写入,会产生一个运行时错误。

Go还提供了切片(slices),作为数组的变形。一个切片(slice)表示一个数组内的连续分段,支持程序员指定底层存储的明确部分。构建一个切片 的语法与访问一个数组元素类似:

/* Construct a slice on ary that starts at s and is len elements long */ s1 := ary[s:len] /* Omit the length to create a slice to the end of ary */ s2 := ary[s:] /* Slices behave just like arrays */ s[0] == ary[s] //=> true // Changing the value in a slice changes it in the array ary[s] = 1 s[0] = 42 ary[s] == 42 //=> true

该切片所引用的数组分段可以通过将新的切片赋值给同一变量来更改:

/* Move the start of the slice forward by one, but do not move the end */ s2 = s2[1:] /* Slices can only move forward */ s2 = s2[-1:] // this is a compile error

切片的长度可以更改,只要不超出切片的容量。切片s的容量是数组从s[0]到数组尾端的大小,并由内建的cap()函数返回。一个切片的长度永远不能超出它的容量。

这里有一个展示长度和容量交互的例子:

a := [...]int{1,2,3,4,5} // The ... means "whatever length the initializer has" len(a) //=> 5 /* Slice from the middle */ s := a[2:4] //=> [3 4] len(s), cap(s) //=> 2, 3 /* Grow the slice */ s = s[0:3] //=> [3 4 5] len(s), cap(s) //=> 3, 3 /* Cannot grow it past its capacity */ s = s[0:4] // this is a compile error

通常,一个切片就是一个程序所需要的全部了,在这种情况下,程序员根本用不着一个数组,Go有两种方式直接创建切片而不用引用底层存储:

/* literal */ s1 := []int{1,2,3,4,5} /* empty (all zero values) */ s2 := make([]int, 10) // cap(s2) == len(s2) == 10

Map类型

几乎每个现在流行的动态语言都有的数据类型,但在C中不具备的,就是dictionary。Go提供了一个基本的dictionary类型叫做map。下 面的例子展示了如何创建和使用Go map:

m := make(map[string] int) // A mapping of strings to ints /* Store some values */ m["foo"] = 42 m["bar"] = 30 /* Read, and exit program with a runtime error if key is not present. */ x := m["foo"] /* Read, with comma-ok check; ok will be false if key was not present. */ x, ok := m["bar"] /* Check for presence of key, _ means "I don't care about this value." */ _, ok := m["baz"] // ok == false /* Assign zero as a valid value */ m["foo"] = 0; _, ok := m["foo"] // ok == true /* Delete a key */ m["bar"] = 0, false _, ok := m["bar"] // ok == false

面向对象

Go语言支持类似于C语言中使用的面向对象风格。数据被组织成structs,然后定义操作这些structs的函数。类似于Python,Go语言提供 了定义函数并调用它们的方式,因此语法并不会笨拙。

 

0
0
分享到:
评论

相关推荐

    Google Go初级读本

    标题《Google Go初级读本》表明这是一本面向初学者介绍Google开发的Go语言的入门书籍。Go语言,又称为Golang,由Google工程师在2007年启动开发,并于2009年首次公开发布,旨在改进C等传统系统编程语言的效率与安全性...

    go初级读本

    Go语言初级读本。~~~~~~~~~~ Go语言是什么? Google最近发布新型的编程语言,Go。它被设计为将现代编程语言的先进 性带入到目前仍由C语言占统治地位的系统层面。然而,这一语言 仍在试验阶段并在不断演变...

    PLC初级读本.rar

    编程语言: PLC的编程主要采用梯形图(Ladder Diagram,LD)、语句表(Structured Text,ST)、功能块图(Function Block Diagram,FBD)和顺序功能图(Sequential Function Chart,SFC)等国际标准编程语言。初学者...

    《通风与安全初级读本》考试题库完整.doc

    《通风与安全初级读本》考试题库完整.doc

    Tarea01:入门读本

    "Tarea01:入门读本" 涵盖了初学者需要掌握的基本概念和技能,让我们深入探讨这个主题。 1. HTML基本结构:每个HTML文件都由&lt;!DOCTYPE&gt;声明开始,它告诉浏览器文档类型和版本。接着是标签,它是整个文档的根元素。在...

    c++使用说明书(初级读本)

    《C++使用说明书(初级读本)》是一本专为初学者设计的教程,它将带你逐步走进C++的世界,领略编程的魅力。书中的内容既包括中文解释,也有英文对照,这种双语结合的方式对语言的理解和编程技能的提升都大有裨益。 ...

    继续教育:诚信建设读本考试.pdf

    继续教育:诚信建设读本考试.pdf

    《通风与安全初级读本》考试题及答案.pdf

    《通风与安全初级读本》是一本针对矿井通风与安全基础理论的教材,涵盖了矿井空气成分、安全标准、有害气体以及通风动力与通风阻力等方面的知识。以下是根据提供的部分内容提炼出的相关知识点: 1. 矿井空气成分:...

    六西格玛实施技巧:绿带读本

    标题和描述均提到了“六西格玛实施技巧:绿带读本”,这明确指出了本文档的主题聚焦于六西格玛方法论在实践中的应用,尤其是针对绿带级别的培训和指导。六西格玛是一种质量管理策略,旨在通过减少过程变异性来提高...

    C++初级读本——Many of the

    Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and Addison-Wesley was aware of a ...

    牛津通识读本:数学

    牛津通识读本:数学 作 者: (英)蒂莫西·高尔斯 著,刘熙 译 出版时间:2014 内容简介  所有人在日常生活中都会接触到数学问题,多数人却又对之心存畏惧。在这本极为易读又充满趣味的小书中,蒂莫西·高尔斯...

    漫话IP:TCP_IP基础知识读本

    漫话IP:TCP_IP基础知识读本

    MPEG 基础和协议分析指南(初级读本)

    MPEG 是目前最常用的一项音频/ 视频压缩技术,它实际 上并不是一个单一的标准,而是包括了适合于各种不同 应用的一系列标准,但这些标准是以一些共同理论为基 础的。MPEG是活动图象专家组的缩写词,该专家组是联 ...

Global site tag (gtag.js) - Google Analytics