Go语言入门经典

978-7-115-48503-8
作者: [英]乔治 奥尔波(George Ornbo)
译者: 张海燕
编辑: 陈聪聪龚昕岳

图书目录:

详情

本书讲解了使用Go语言编写高质量程序的方法,其内容涵盖了Go语言特性和标准库安装包,Go与JavaScript的对比,Go命令行工具,Go中的基本概念(比如类型、变量、函数、控制结构、指针、接口等)、错误处理、goroutines和channels、Go代码测试、使用Go编写HTTP客户端与服务器、处理JSON和文件、部署GO代码等。本书适合想要掌握Go语言的零基础用户学习。

图书摘要

版权信息

书名:Go语言入门经典

ISBN:978-7-115-48503-8

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    [英] 乔治•奥尔波(George Ornbo)

译    张海燕

责任编辑 陈聪聪

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315


George Ornbo:Sams Teach Yourself Go in 24 Hours

ISBN: 978-0-672-33803-8

Copyright © 2018 by Pearson Education, Inc.

Authorized translation from the English languages edition published by Pearson Education, Inc.

All rights reserved.

本书中文简体字版由美国Pearson公司授权人民邮电出版社出版。未经出版者书面许可,对本书任何部分不得以任何方式复制或抄袭。

版权所有,侵权必究。


Go语言是谷歌推出的一种全新的编程语言,旨在不损失应用程序性能的情况下降低代码的复杂性,具有“部署简单、并发性好、语言设计良好、执行性能好”等优势,目前国内诸多IT公司均已采用Go语言开发项目。

本书分为24章,讲解了使用Go语言编写高质量程序的方法,其内容涵盖了Go语言特性和标准库安装包,Go与JavaScript的对比,Go命令行工具,Go中的基本概念(比如类型、变量、函数、控制结构、指针、接口等)、错误处理、Goroutine和通道、Go代码测试、使用Go编写HTTP客户端与服务器、处理JSON和文件、部署Go代码等。

本书适合想要掌握Go语言的零基础读者以及对Go语言感兴趣的程序员学习,还可作为高等院校教授Go语言课程的教材。


George Ornbo是一位软件工程师、博主和作家,拥有14年的软件开发经验,其客户既有初创公司,也有大型企业客户;熟悉众多编程语言、UNIX和Web底层协议。当前供职于伦敦的一家区块链初创公司。


谨以此书献给Bea和Fin,有你们俩真是我天大的福分!


感谢Laura Lewin和Pearson编辑团队给我写作本书的机会。还要感谢Sheri Replin所做的出色工作!

感谢Bala Natarajan和Yoshiki Shibata为本书所做的技术审校工作,感谢他们提出的大量卓越的改进建议。

感谢Robert Griesemer、Rob Pike和Ken Thompson设计出了Go语言。


Go(Golang)语言是编程语言设计的又一次尝试,是对类C语言的重大改进。它让您能够访问底层操作系统,还提供了强大的网络编程和并发编程支持。

Go语言用途众多,其中包括如下几种。

很多重要的开源项目都是使用Go语言开发的,其中包括Go-Ethereum、Terraform、Kubernetes和Docker。Go语言给开源界带来了重大影响,有望提高开源项目的成功率。

本书不要求读者具备任何编程或计算机方面的经验,但如果对编程有基本的认识将大有裨益。由于Go代码主要是从终端运行的,因此熟悉终端以及如何在其中执行基本命令是十分必要的。最后,鉴于Go语言常用于系统编程和网络编程,因此对互联网的工作原理有些了解也将很有帮助,虽然这并非必要的。

如果您要创建系统程序或基于网络的程序,Go语言是很不错的选择。作为一种相对较新的语言,它是由经验丰富且受人尊敬的计算机科学家设计的,旨在应对创建大型并发网络程序面临的挑战。如果您觉得Java或C语言的语法导致编程很难,那么Go语言将可能提供更佳的体验。对具备诸如Ruby、Python、JavaScript等动态语言使用经验的程序员来说,Go语言提供了类型安全,同时又不像传统语言那么死板。

本书首先介绍Go语言基础知识,包括搭建Go语言编程环境以及运行第一个Go程序。接下来介绍一些重要的Go语言知识,包括字符串、函数、结构体和方法。您将学会如何使用Goroutine和通道,这些是Go语言特有的功能,它们避免了并发编程的大部分难题。

然后,您将学习如何调试和测试Go语言代码,并学会一些帮助编写独具Go语言风格代码的技巧。

接下来,您将学习如何编写基本的命令行程序、HTTP服务器和HTTP客户端,并学习如何处理JSON数据和文件。

最后,您将学习正则表达式相关的知识、如何处理时间以及如何将Go应用程序部署到生产环境中。

本书每章都有多个代码示例,旨在帮助您学习Go语言,它们与正文一样重要,强烈建议您在阅读过程中运行这些示例代码。本书的示例代码可在异步社区本书页面中下载。


本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。

本书提供如下资源:

本书配套资源请到异步社区的本书购买页面中下载。

要获得以上配套资源,请在异步社区本书页面中点击 ,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

扫描下方二维码,您将会在异步社区微信服务号中看到本书信息及相关的服务提示。

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/ selfpublish/submission即可)。

如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。

异步社区

微信服务号


本章介绍如下内容。

通过阅读本章,您将知道Go是什么以及创建它的动机是什么。您将学习如何安装Go并运行第一个程序。您还将了解Go Gopher,它会在本书中时不时地蹦出来。

Go(或Golang)是Google在2007年开发的一种开源编程语言,出自Robert Griesemer、Rob Pike和Ken Thompson之手。2009年11月10日,Google Open Source Blog向全球发布了这款语言;公告指出Go的主要目标是“兼具Python等动态语句的开发速度和C或C++等编译型语言的性能与安全性”。

对语言进行评估时,明白设计者的动机以及语言要解决的问题很重要。Go语言的设计者都是计算机科学领域的重量级人物。在20世纪70年代,Ken Thompson设计并实现了最初的UNIX操作系统,仅从这一点说,他对计算机科学的贡献怎么强调都不过分。他还与Rob Pike合作设计了UTF-8编码方案。除帮助设计UTF-8外,Rob Pike还帮助开发了分布式多用户操作系统Plan 9,并与人合著了The Unix Programming Environment,对UNIX的设计理念做了正统的阐述。Robert Griesemer就职于Google,对语言设计有深入的认识,并负责Chrome浏览器和Node.js使用的Google V8 JavaScript引擎的代码生成部分。

这些计算机科学领域的重量级人物设计Go语言的初衷是满足Google的需求。设计此语言花费了两年的时间,融入了整个团队多年的经验及对编程语言设计的深入认识。设计团队借鉴了Pascal、Oberon和C语言的设计智慧,同时让Go语言具备动态语言的便利性。因此,Go语言体现了经验丰富的计算机科学家的语言设计理念,是为全球最大的互联网公司之一设计的。Go语言的所有设计者都说,设计Go语言是因为C++给他们带来了挫败感。在Google I/O 2012的Go设计小组见面会上,Rob Pike是这样说的:

“我们做了大量的C++开发,厌烦了等待编译完成,尽管这是玩笑,但在很大程度上来说也是事实。”

您无须知道Go语言的设计历史就能使用它。您只需知道,Go语言的设计和实现体现了多位计算机专家多年的经验以及对其他编程语言优缺点的深入认识。因C++的不良体验而出现的Go语言是一门现代编程语言,可用来创建性能卓越的Web服务器和系统程序。

Go使用编译器来编译代码。编译器将源代码编译成二进制(或字节码)格式;在编译代码时,编译器检查错误、优化性能并输出可在不同平台上运行的二进制文件。要创建并运行Go程序,程序员必须执行如下步骤。

1.使用文本编辑器创建Go程序。

2.保存文件。

3.编译程序。

4.运行编译得到的可执行文件。

这不同于Python、Ruby和JavaScript等语言,它们不包含编译步骤。有关使用编译器的优缺点,将在第2章介绍。Go自带了编译器,因此无须单独安装编译器。

Go可用于FreeBSD、Linux、Windows和macOS等操作系统。如果您使用的是这些操作系统的较新版本,它们很可能支持Go。有关对这些平台的要求,请参阅Go网站列出的系统需求。推荐尽可能使用操作系统自带的包管理器来安装Go。

开发者也可使用从Golang网站下载的文件来安装Go。如果您是新手,推荐使用安装程序来安装,尽管没有用于Linux系统的Go安装程序,但通常可使用包管理器来安装;如果您是经验丰富的Linux用户,可使用源代码来安装Go,如果您使用的是Windows或macOS系统,只需下载相应的文件并双击它,再按说明完成安装过程即可。您将看到一个标准的安装程序窗口,如图1.1所示。

图1.1 在Windows系统中运行Go安装程序

安装程序运行完毕后,打开命令提示符并执行命令go version。如果您看到包含版本号的输出(如图1.2所示),就说明正确地安装了Go。

图1.2 在Windows系统中核实正确地安装了Go

要完成安装,还需为Go项目创建目录结构。为此,使用“开始”菜单打开命令提示符,并创建如下目录(如图1.3所示)。

mkdir %USERPROFILE%\go
mkdir %USERPROFILE%\go\bin
mkdir %USERPROFILE%\go\pkg
mkdir %USERPROFILE%\go\src

图1.3 为Go项目创建目录结构

创建这些文件夹后,就可添加环境变量GOPATH了。在Windows系统中添加这个环境变量的步骤如下。

1.单击“开始”菜单中的“控制面板”。

2.搜索“环境变量”。

3.单击“编辑账户的环境变量”,打开如图1.4所示的对话框。

4.单击“New(新建)”按钮。

5.在Variable(变量名)文本框中输入GOPATH。

6.在Value(值)文本框中输入%USERPROFILE%\go。

7.单击“保存”按钮。

图1.4 在Windows系统中设置环境变量GOPATH

如果您打开了命令提示符,将其关闭再重新打开。在提示符下执行如下命令,以检查是否设置了环境变量GOPATH:

echo %GOPATH%
C:\Users\george\go

安装程序运行完毕后,打开命令提示符并执行命令go version。如果您看到包含版本号的输出(如图1.5所示),就说明正确地安装了Go。

图1.5 在macOS系统中核实是否正确地安装了Go

要完成安装,还需要为Go项目创建目录结构。为此,打开终端并创建如下目录:

mkdir $HOME/go
mkdir $HOME/go/bin
mkdir $HOME/go/pkg
mkdir $HOME/go/src

为设置环境变量GOPATH,请编辑.bashrc(如果您运行的是其他shell,请编辑相应的文件),在其中添加如下内容。.bashrc位于您的主(home)目录下。

export GOPATH=$HOME/go

重新加载shell或关闭并重新打开终端。在提示符下执行如下命令,以检查是否设置了环境变量GOPATH:

echo $GOPATH
/home/george/go

Go根据您的环境配置行事。作为一个开源项目,代码分享也很重要。为在以后能够分享代码,推荐您创建一个Github账户。如果您没有这样的账户,则可前往Github网站免费创建;如果您要使用其他服务,如Gitlab或Bitbucket,则需要在后面的命令中将github.com替换为您要使用的服务的URL。如果您不熟悉Git和GitHub,也不用担心,本书后面会介绍。创建Github账户后,像下面这样创建用于存储源代码的文件夹:

// Linux / macOS
mkdir -p $GOPATH/src/github.com/[your github username]

// Windows
mkdir %GOPATH%\src\github.com\[your github username]

TRY IT YOURSELF▼ 

显示Hello World!

在这个示例中,您将运行第一个Go程序!

1.创建一个用于存储这个程序的文件夹,再切换到这个文件夹。

2.打开本书代码示例中的文件hour01/example01。

3.在刚创建的文件夹hello中,创建一个名为main.go的文件。

4.将文件hour01/example01的内容复制到main.go中。

5.在文件夹hello中,执行命令go build。

6.在文件夹中,执行命令run./main(Linux或macOS系统)或main.exe(Windows系统)。

7.您将在控制台中看到Hello World!。

8.祝贺您运行了第一个Go程序!

现在该来编写著名的Hello World程序了!如果您已安装好Go,则只要有文本编辑器就可以创建Go程序了。如果您还没有喜欢的文本编辑器,可考虑使用Sublime、Textmate、Notepad++、Atom、Vim、Emacs等。至于哪款文本编辑器最好,程序员们就此争论得非常激烈,但如果您是新手,选择您用得顺手的编辑器就好。Go对文本编辑器没有特殊要求,因此如果您只是想尝试一下Go,使用操作系统提供的默认文本编辑器就可以了。

程序清单1.1列出了Go程序Hello World的代码。这个程序很简单,只是向终端打印一行文本。

程序清单1.1 Hello World

 1: package main
 2:
 3: import (
 4:   "fmt"
 5: )
 6:
 7: func main() {
 8:   fmt.Println("Hello World!")
 9: }
// Linux / macOS
mkdir -p $GOPATH/src/github.com/[your github username]/hello
cd $GOPATH/src/github.com/[your github username]/hello

// Windows
mkdir %GOPATH%\src\github.com\[your github username]\hello
cd %GOPATH%\src\github.com\[your github username]\hello

 

提示:大多数语言都提供了Hello World示例。

Hello World是一个简单的编程示例,用于展示编程语言的语法。它常用于检查安装是否正确以及简单地介绍语言。它还能够让您对不同的编程语言进行快速比较。

编译并运行文件是开发过程中的一个常见步骤,Go提供了完成这个步骤的快捷途径。使用下面的命令编译并运行程序:

go run main.go

不同于go build,go run不会创建可执行文件。在开发Go代码时,go run提供了一种便利的方式,因为没有必要将编译和执行步骤分开。另外,也不需要运行go clean来清除可执行文件。

Go编程语言有一个吉祥物!在会议、文档页面和博文中,大多会包含如图1.6所示的Go Gopher,这是才华横溢的插画家Renee French设计的,她也是Go设计者之一Rob Pike的妻子。

图1.6 Go吉祥物Gopher(由Renee French设计)

本章介绍了Go语言的设计者以及它们设计Go语言的动机。您安装了Go并运行了第一个程序;还了解了命令go build和go run的差别以及Go Gopher。在一章内学习了这么多内容真的很不错!

问:既有的语言很多,为何还要设计Go语言?

答:设计Go语言是因为Java和C++ 等传统语言繁琐、缓慢而难以理解。Go语言的设计者借鉴了Python动态类型语言的优点,旨在打造一款易于使用并可用于开发高流量生产系统的语言。

问:编译器生成的可执行文件很大,但源代码文件很小。为何会这样?

答:在编译器生成的二进制文件中,必须包含执行程序所需的一切。这带来的缺点是二进制文件比源代码文件大,但优点是无须安装依赖就能运行程序。

问:该使用命令go build还是go run?

答:在开发阶段,推荐使用命令go run;程序开发完毕,可以分享时,建议使用go build。

作业包含小测验和答案,旨在加深对本章内容的理解。请尽可能先回答所有的问题再看后面的答案。

1.要运行Go程序,都需要什么?

2.您能说出go build和go run的不同之处吗?

3.Go Gopher是什么?

1.除计算机外,您只需终端和文本编辑器。

2.命令go build执行编译,生成一个可执行的二进制文件,这个文件可用来运行程序;命令go run编译并运行程序。

3.Go Gopher是Go语言的吉祥物,其身影在整个Go生态系统中随处可见。

1.修改程序Hello World,让它显示您想说的其他文本。使用命令go build编译这个程序,再运行生成的可执行文件。再次修改要显示的文本,并使用命令go run运行这个程序。您现在明白这两个命令的差异了吗?

2.在网上搜索使用其他各种语言编写的Hello World程序。您能发现这些程序与本章的示例程序有什么相同之处吗?

3.如果有时间,请观看Rob Pike在2009年介绍Go编程语言的视频,其中概述了Golang的众多设计目标。


本章介绍如下内容。

Go是一种静态类型语言,而静态类型是一个必须理解的概念,如果您不是学计算机的,或者使用过Python、JavaScript等动态语言,这尤其重要。本章介绍数据类型,并帮助您理解强类型语言和动态类型语言的差别。您将学习Go语言类型系统的工作原理及其基本类型。

数据类型让编程语言、编译器、数据库和代码执行环境知道如何操作和处理数据。例如,如果数据类型为数字,通常可对其执行数学运算。编程语言和数据库常常根据数据类型赋予程序不同的功能和性能。大多数编程语言还提供了用于处理常见数据的标准库,而数据库提供了查询语言,让程序员能够根据底层数据类型来查询数据以及与之交互。无论数据类型是否被显式地声明,它们都是重要的编程和计算结构。

TRY IT YOURSELF▼ 

传递类型不正确的参数

在这个示例中,您将明白Go编译器是如何实现类型系统的。

1.打开本书代码示例中的hour02/example04.go。

2.在终端执行命令go run example04.go来运行这个程序。

3.您将看到如下错误消息。

所谓强类型语言,指的是错误地使用了类型时,编译器将引发错误;所谓动态类型(也叫松散类型或弱类型)语言,指的是为了执行程序,运行时会将一种类型转换为另一种类型,或者编译器没有实现类型系统。哪种语言更好呢?这存在很大的争议,计算机科学家看重强类型语言的正确性和安全性,而其他人则看重动态语言的简单性和开发速度。

下面是静态类型语言的一些优点。

下面是动态类型语言的一些优点。

在Go中,程序员可显式地声明类型,也可让编译器推断类型。在本章中,我们将显式地声明类型,以帮助您理解。程序清单2.1是一个向终端打印消息的程序。

./example04.go:11: cannot use s (type string) as type int in argument to addition

程序清单2.1 类型简介

 1: package main
 2:
 3: import (
 4:   "fmt"
 5: )
 6:
 7: func sayHello(s string) string {
 8:   return "Hello " + s
 9: }
10:
11: func main() {
12:   fmt.Println(sayHello("George"))
13: }

如果您不能完全理解程序清单2.1,也不用担心。这里的重点是函数sayHello的声明。从参数声明可知,这个函数接受一个类型为string的参数;这个函数的返回值也是字符串。因此,编译这个程序时,编译器将检查传递给这个函数的参数是否是字符串;如果不是,编译器将引发错误。这正是我们希望的,因为这意味着错误可能根本不会让用户遇到。

为了比较强类型语言和动态类型语言,下面来看一个JavaScript示例。JavaScript是一种使用广泛的动态类型语言,如果您不熟悉,也没关系。这里的重点是看看它在处理类型方面有何不同。

程序清单2.2是一个简单的JavaScript函数,它接受两个值,将它们相加并返回结果。

程序清单2.2 简单的JavaScript函数

 1: var addition = function (a, b) {
 2:   return x + y;
 3: };

给这个函数提供两个数字时,它能够正确地运行。

addition(1,3)
4

然而,如果向它传递一个数字和一个字符串,结果将很怪异。

addition(1,"three")
1three

在这种情况下,这个函数返回一个字符串。怎么会这样呢?虽然JavaScript有类型的概念,但其类型使用规则非常宽松。在这个示例中,JavaScript对数字值执行类型转换,将其转换为字符串,因此返回字符串1three。JavaScript提供的这种灵活性虽然很有吸引力,但可能导致微妙乃至灾难性的Bug。

假设有个程序使用上述addition函数来接受输入并将其存储到数据库中。数据库通常有数据类型的概念,很多还有整数的概念。整数是没有小数部分的数字,可正可负。如果数据库将字段定义成了整型,就会要求提供给该字段的值为整数。

前述JavaScript函数addition可能返回一个字符串,也可能返回一个整数。如果传递给它的值至少有一个字符串,返回的就是字符串。如果这个返回值被插入到需要整数的数据库字段中,将引发错误。更糟糕的是,这种错误发生在运行阶段,这意味着它将影响使用程序的用户。这种错误除非得到妥善处理,否则可能导致程序崩溃。

而在使用Go语言编写的函数中,对参数和返回值的类型都做了声明。

程序清单2.3是一个使用Go语言编写的函数,这个函数指出它接受两个int值,并返回一个int值。即便不看这个函数的实现,也知道它接受两个整数并返回一个整数。如果程序员错误地将一个字符串传递给这个函数,编译器将捕获这种错误。

程序清单2.3 Go语言中的类型

 1: package main
 2:
 3: import (
 4:   "fmt"
 5: )
 6:
 7: func addition(x int, y int) int {
 8:   return x + y
 9: }
10:
11: func main() {
12:   fmt.Println(addition(2,4))
13: }

在程序清单2.4所示的示例中,向函数传递了类型不正确的参数。在这个示例中,将在编译阶段发现这种错误,避免用户遭遇软件崩溃。

程序清单2.4 传递类型不正确的参数

 1: package main
 2:
 3: import (
 4:   "fmt"
 5: )
 6:
 7: func addition(x int, y int) int {
 8:   return x + y
 9: }
10:
11: func main() {
12:   var s string = "three"
13:   fmt.Println(addition(1, s))
14: }

如果您尝试运行这个程序,将出现编译错误。编译错误提供了有用的信息,让您知道出现错误的原因。在这里,原因是在需要int的地方使用了字符串。

cannot use s (type string) as type int in argument to addition

Go编译器还能捕获其他常见的错误,如传递的参数太多或太少。

TRY IT YOURSELF▼ 

声明布尔变量并给它重新赋值

在这个示例中,您将明白如何初始化布尔变量以及给它重新赋值。

1.打开本书代码示例中的hour02/example06.go。

2.在终端中执行命令go run example06.go以运行这个程序。

3.您将看到给其中的布尔变量重新赋值了。

对类型有了基本认识后,就可探索Go是如何实现一些基本数据类型的了。首先来看布尔类型。布尔值只能为true或false。虽然有些语言允许使用值1和0来表示true和false,但Go语言不允许。可像下面这样声明布尔变量。

var b bool

如果没有给布尔变量赋值,它将默认为false。程序清单2.5声明了一个布尔变量,再将其打印到终端。

程序清单2.5 声明布尔变量

 1: package main
 2:
 3: import (
 4:   "fmt"
 5: )
 6:
 7: func main() {
 8:   var b bool
 9:   fmt.Println(b)
10: }

布尔变量可在声明后重新赋值(参见程序清单2.6),它们是很有用的编程元素。

  false
  true

程序清单2.6 给布尔变量重新赋值

 1: package main
 2:
 3: import (
 4:   "fmt"
 5: )
 6:
 7: func main() {
 8:   var b bool
 9:   fmt.Println(b)
10:   b = true
11:   fmt.Println(b)
12: }

对编程来说,数值不可或缺。然而,如果您没有计算机科学或数学方面的知识,可能对有些术语感到迷惑。您可能听说过浮点数、整数、无符号整数、8位、64位、bigint、smallint、tinyint,这些都是整型(数值)类型。要明白这些术语的含义,必须知道数字在计算机内部是以二进制位的方式存储的。二进制位就是一系列布尔值,取值要么为1,要么为0。1位可表示1或0,对于4位整数,表2.1对其二进制表示和十进制表示做了比较。从该表可知,4位可表示16个不同的数字。

表2.1 4位的无符号整数

二进制

十进制

0000

0

0001

1

0010

2

0011

3

0100

4

0101

5

0110

6

0111

7

1000

8

1001

9

1010

10

1011

11

1100

12

1101

13

1110

14

1111

15

对于带符号整数,需要使用一位来表示符号,这通常是符号−。表2.1列出了无符号的4位整数,其取值范围为0~15。带符号整数可正可负,因此4位带符号整数的取值范围为−8到7,如表2.2所示。

表2.2 4位的带符号整数

二进制

十进制

0000

0

0001

1

0010

2

0011

3

0100

4

0101

5

0110

6

0111

7

1000

−8

1001

−7

1010

−6

1011

−5

1100

−4

1101

−3

1110

−2

1111

−1

 

提示:可使用的最大数值取决于计算机处理器。

在计算机中,可使用的最大数值取决于计算机处理器的体系结构。当今的计算机大多是64位的,支持的最大无符号整数为9223372036854775807。第一代微处理器有些只有4位,这意味着只能表示−8~7的带符号整数!

在Go语言中,声明整型变量的方式如下。

var i int = 3

类型int表示带符号整数,因此可正可负。根据计算机的底层体系结构,int可能是32位的带符号整数,也可能是64位的带符号整数。除非要处理的数字非常大,或者非常在乎性能,否则只需使用int,而无须关心编译器是如何做的。

浮点数是带小数点的数字,如11.2、0.1111、43.22。整数不能包含小数部分,因此要处理分数,必须使用浮点数。根据实际数字的大小,Go语言中的浮点数可以是32位的,也可以是64位的。在大多数现代计算机中,推荐使用float64。

var f float32 = 0.111

字符串可以是任何字符序列,其中的字符可能是数字、字母和符号。下面是一些简单的字符串。

几乎所有的编程语言都支持字符串,它们通常包含数字、字母或符号。在Go语言中,声明并初始化字符串变量很简单。

var s string = "foo"

字符串变量可以为空,这种变量非常适合用来累积其他变量中的数据以及存储临时数据。

var s string = ""

创建字符串变量后,可将其与其他数据相加,但不能修改原来的值。下面的代码创建一个空字符串,再将字符串foo附加到末尾,这在Go语言中是合法的。

var s string = ""
s += "foo"

不能对字符串执行数学运算,即便它看起来像个数字。要想对看起来像数字的字符串执行数学运算,必须先将其转换为数字类型。

数组是几乎所有编程语言都支持的另一种数据类型,这是一种比较复杂的类型,因为它包含一系列元素。例如,要表示乐队的成员,使用字符串数组是不错的选择。声明数组时,必须指定其长度和类型。

var beatles [4]string

在这个示例中,方括号内的数字表示数组的长度,而紧跟在方括号后的是数组的类型——这里为字符串。

beatles[0] = "John"
beatles[1] = "Paul"
beatles[2] = "Ringo"
beatles[3] = "George"

数组将在第6章详细介绍。

注意:数组索引从0开始。

您可能注意到了,在上述变量声明中,指定的数组长度为4,但访问这个数组的元素时,索引最大为3。这是因为在所有数组中,索引都从0开始。刚接触时,您可能对这一点感到迷惑。

TRY IT YOURSELF▼ 

检查类型

1.打开本书代码示例中的hour02/example07.go。

2.在终端中执行命令go run example07.go以运行这个程序。

3.控制台中将显示了变量的类型。

有些情况下,需要检查变量的类型,为此可使用标准库中的reflect包,它让您能够访问变量的底层类型。在大多数情况下,编译器都能发现类型不正确的情形,但在调试或必须核实底层类型时,reflect包将很有用,如程序清单2.7所示。

程序清单2.7 使用reflect包检查变量类型

 1: package main
 2:
 3: import (
 4:   "fmt"
 5:   "reflect"
 5: )
 6:
 7: func main() {
 8:   var s string = "string"
 9:   var i int = 10
10:   var f float32 = 1.2
11:
12:   fmt.Println(reflect.TypeOf(s))
13:   fmt.Println(reflect.TypeOf(i))
14:   fmt.Println(reflect.TypeOf(f))
15: }
  string
  int
  float32

TRY IT YOURSELF▼ 

类型转换

在这个示例中,您将明白如何使用strconv包来执行类型转换。

1.在文本编辑器中打开文件hour02/example08.go,并尝试理解这个示例是做什么的。

2.在终端中执行命令go run example08.go以运行这个程序。

3.您将在控制台中看到显示的类型,这表明已经将布尔数据转换成了字符串。

将数据从一种类型转换为另一种类型是常见的编程任务,这通常是在从网络或数据库读取数据时进行的。Go标准库提供了良好的类型转换支持。strconv包提供了一整套类型转换方法,可用于转换为字符串或将字符串转换为其他类型。

假设有一个字符串变量s,其值为“true”,要将其用于布尔比较,必须先转换为布尔类型。

var s string = "true"
b, err := strconv.ParseBool(s)

变量b的类型为布尔值。同样,布尔值也可转换为字符串。

s := strconv.FormatBool(true)
fmt.Println(s)

程序清单2.8是一个将布尔值转换为字符串的示例。

  bool
  string

程序清单2.8 类型转换和类型检查

 1: package main
 2:
 3: import (
 4:   "fmt"
 5:   "strconv"
 6:   "reflect"
 7: )
 8:
 9: func main() {
10:   var b bool = true
11:   fmt.Println(reflect.TypeOf(b))
12:   var s string = strconv.FormatBool(true)
13:   fmt.Println(reflect.TypeOf(s))
14: }

 

提示:理解数据结构。

在编程中,错误地理解数据类型通常会导致Bug出现。使用数据源前,请先花点时间搞明白数据类型。如果数据源为数据库,请了解数据库模式(schema)及其使用的数据类型,这将节省大量的调试时间!

本章简要地介绍了数据类型。您知道了强类型语言和动态类型语言的差别以及它们的优缺点,了解了Go语言中一些基本数据类型,学习了如何检查变量的数据类型以及如何进行类型转换。本章介绍的内容很多,而且包含了一些基本的计算知识。

问:字符串“1234”为何是字符串,而不是数字?

答:不管字符串看起来有多像数字,它都是字符串。要将其作为数字使用,必须先转换为数字类型。

问:数组能存储不同类型的数据吗?

答:能。有关这样的示例,请参阅第6章内容。

问:我熟悉C等其他语言。请问在Go语言中,我需要负责分配内存吗?

答:Go负责分配内存和执行垃圾收集。虽然正常的内存使用规则依然适用,但您无须直接管理内存。

作业包含小测验和答案,旨在加深对本章内容的理解。请尽可能先回答所有的问题再看后面的答案。

1.强类型语言有何优缺点?

2.带符号整数和无符号整数有何不同?

3.如何检查变量的类型?

1.强类型语言的数据完整性更高,且编译器通常能够在代码执行前发现Bug。与使用动态类型语言相比,使用强类型语言时,开发速度可能慢一些,条条框框也多一些。鉴于强类型语言过于严格且编译速度缓慢,Go语言应运而生,旨在兼具动态类型语言的速度与灵活性和静态类型语言的性能与完整性。

2.无符号整数没有占据位的符号。4位无符号整数的可能取值为16个,只能为正;4位带符号整数的可能取值也是16个,但可正可负。

3.要检查变量的类型,可使用reflect包。要了解reflect包,请参阅程序清单2.6。

1.列举本章介绍的数字类型。阐述不同数据类型的差别,如果必要请参阅本章前面的内容。

2.创建一个简短的程序,将字符串变量和int变量之间进行转换。

3.如果有时间,请观看Gary Bernhardt的讲解视频WAT。该视频谈论了包括JavaScript在内的动态类型语言。切忌不分青红皂白地全盘接受!


相关图书

JUnit实战(第3版)
JUnit实战(第3版)
Kafka实战
Kafka实战
Rust实战
Rust实战
PyQt编程快速上手
PyQt编程快速上手
Elasticsearch数据搜索与分析实战
Elasticsearch数据搜索与分析实战
玩转Scratch少儿趣味编程
玩转Scratch少儿趣味编程

相关文章

相关课程