learn.lianglianglee.com/专栏/22 讲通关 Go 语言-完/01 基础入门:编写你的第一个 Go 语言程序.md.html
2022-09-06 22:30:37 +08:00

336 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>01 基础入门:编写你的第一个 Go 语言程序.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/22 讲通关 Go 语言-完/00 开篇词 Go 为开发者的需求设计,带你实现高效工作.md.html">00 开篇词 Go 为开发者的需求设计,带你实现高效工作</a>
</li>
<li>
<a class="current-tab" href="/专栏/22 讲通关 Go 语言-完/01 基础入门:编写你的第一个 Go 语言程序.md.html">01 基础入门:编写你的第一个 Go 语言程序</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/02 数据类型:你必须掌握的数据类型有哪些?.md.html">02 数据类型:你必须掌握的数据类型有哪些?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/03 控制结构if、for、switch 逻辑语句的那些事儿.md.html">03 控制结构if、for、switch 逻辑语句的那些事儿</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/04 集合类型:如何正确使用 array、slice 和 map.md.html">04 集合类型:如何正确使用 array、slice 和 map</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/05 函数和方法Go 语言中的函数和方法到底有什么不同?.md.html">05 函数和方法Go 语言中的函数和方法到底有什么不同?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/06 struct 和 interface结构体与接口都实现了哪些功能.md.html">06 struct 和 interface结构体与接口都实现了哪些功能</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/07 错误处理:如何通过 error、deferred、panic 等处理错误?.md.html">07 错误处理:如何通过 error、deferred、panic 等处理错误?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/08 并发基础Goroutines 和 Channels 的声明与使用.md.html">08 并发基础Goroutines 和 Channels 的声明与使用</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/09 同步原语sync 包让你对并发控制得心应手.md.html">09 同步原语sync 包让你对并发控制得心应手</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/10 Context你必须掌握的多线程并发控制神器.md.html">10 Context你必须掌握的多线程并发控制神器</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/11 并发模式Go 语言中即学即用的高效并发模式.md.html">11 并发模式Go 语言中即学即用的高效并发模式</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/12 指针详解:在什么情况下应该使用指针?.md.html">12 指针详解:在什么情况下应该使用指针?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/13 参数传递:值、引用及指针之间的区别?.md.html">13 参数传递:值、引用及指针之间的区别?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/14 内存分配new 还是 make什么情况下该用谁.md.html">14 内存分配new 还是 make什么情况下该用谁</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/15 运行时反射:字符串和结构体之间如何转换?.md.html">15 运行时反射:字符串和结构体之间如何转换?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/16 非类型安全:让你既爱又恨的 unsafe.md.html">16 非类型安全:让你既爱又恨的 unsafe</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/17 SliceHeaderslice 如何高效处理数据?.md.html">17 SliceHeaderslice 如何高效处理数据?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/18 质量保证Go 语言如何通过测试保证质量?.md.html">18 质量保证Go 语言如何通过测试保证质量?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/19 性能优化Go 语言如何进行代码检查和优化?.md.html">19 性能优化Go 语言如何进行代码检查和优化?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/20 协作开发:模块化管理为什么能够提升研发效能?.md.html">20 协作开发:模块化管理为什么能够提升研发效能?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/21 网络编程Go 语言如何玩转 RESTful API 服务?.md.html">21 网络编程Go 语言如何玩转 RESTful API 服务?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/22 网络编程Go 语言如何通过 RPC 实现跨平台服务?.md.html">22 网络编程Go 语言如何通过 RPC 实现跨平台服务?</a>
</li>
<li>
<a href="/专栏/22 讲通关 Go 语言-完/23 结束语 你的 Go 语言成长之路.md.html">23 结束语 你的 Go 语言成长之路</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>01 基础入门:编写你的第一个 Go 语言程序</h1>
<p>从这节课开始,我会带你走进 Go 语言的世界。我会用通俗易懂的语言,介绍 Go 语言的各个知识点,让你可以从零开始逐步学习,再深入它的世界。不管你以前是否接触过 Go 语言,都可以从这个专栏中受益。</p>
<p>现在让我以一个经典的例子“Hello World”来带你入门 Go 语言,了解它是如何运行起来的。</p>
<h3>Hello, 世界</h3>
<p>如果你学过 C 语言,对这个经典的例子应该不会陌生。通过它,我先带你大概了解一下 Go 语言的一些核心理念,让你对 Go 语言代码有个整体的印象。如下所示:</p>
<p><em><strong>ch01/main.go</strong></em></p>
<pre><code>package main
import &quot;fmt&quot;
func main() {
fmt.Println(&quot;Hello, 世界&quot;)
}
</code></pre>
<p>这五行代码就构成了一个完整的 Go 程序,是不是非常简单?现在我运行这段代码,看看输出的结果,方法是打开终端输入以下命令,然后回车。</p>
<pre><code>$ go run ch01/main.go
Hello, 世界
</code></pre>
<p>其中 go run ch01/main.go 是我输入的命令回车后看到的“Hello, 世界”是 Go 程序输出的结果。</p>
<p>代码中的 go 是一个 Go 语言开发工具包提供的命令,它和你平时常用的 ls 命令一样都是可执行的命令。它可以帮助你运行 Go 语言代码,并进行编译,生成可执行的二进制文件等。</p>
<p>run 在这里是 go 命令的子命令,表示要运行 Go 语言代码的意思。最后的 ch01/main.go 就是我写的 Go 语言代码文件了。也就是说,整个 go run ch01/main.go 表示要运行 ch01/main.go 里的 Go 语言代码。</p>
<h3>程序结构分析</h3>
<p>要让一个 Go 语言程序成功运行起来,只需要 package main 和 main 函数这两个核心部分, package main 代表的是一个可运行的应用程序,而 main 函数则是这个应用程序的主入口。</p>
<p>在“Hello, 世界”这个简单的示例中,包含了一个 Go 语言程序运行的最基本的核心结构。我们以此为例,来逐一介绍程序的结构,了解 Go 语言的核心概念。</p>
<ul>
<li><strong>第一行的 package main</strong> 代表当前的 ch01/main.go 文件属于哪个包,其中 package 是 Go 语言声明包的关键字main 是要声明的包名。在 Go 语言中 main 包是一个特殊的包,代表你的 Go 语言项目是一个可运行的应用程序,而不是一个被其他项目引用的库。</li>
<li><strong>第二行的 import &quot;fmt&quot;</strong> 是导入一个 fmt 包,其中 import 是 Go 语言的关键字,表示导入包的意思,这里我导入的是 fmt 包,导入的目的是要使用它,下面会继续讲到。</li>
<li><strong>第三行的 func main()</strong> 是定义了一个函数,其中 func 是 Go 语言的关键字表示要定义一个函数或者方法的意思main 是函数名,() 空括号表示这个 main 函数不接受任何参数。在 Go 语言中 main 函数是一个特殊的函数,它代表整个程序的入口,也就是程序在运行的时候,会先调用 main 函数,然后通过 main 函数再调用其他函数,达到实现项目业务需求的目的。</li>
<li><strong>第四行的 fmt.Println(&quot;Hello, 世界&quot;)</strong> 是通过 fmt 包的 Println 函数打印“Hello, 世界”这段文本。其中 fmt 是刚刚导入的包要想使用一个包必须先导入。Println 函数是属于包 fmt 的函数这里我需要它打印输出一段文本也就是“Hello, 世界”。</li>
<li><strong>第五行的大括号 }</strong> 表示 main 函数体的结束。现在整个代码片段已经分析完了运行就可以看到“Hello, 世界”结果的输出。</li>
</ul>
<p>从以上分析来看,<strong>Go 语言的代码是非常简洁、完整的核心程序,只需要 package、import、func main 这些核心概念就可以实现。</strong> 在后面的课时中,我还会讲如何使用变量,如何自定义函数等,这里先略过不讲,我们先来看看 Go 语言的开发环境是如何搭建的,这样才能运行上面的 Go 语言代码,让整个程序跑起来。</p>
<h3>Go 语言环境搭建</h3>
<p>要想搭建 Go 语言开发环境,需要先下载 Go 语言开发包。你可以从官网 <a href="https://golang.org/dl/">https://golang.org/dl/</a><a href="https://golang.google.cn/dl/">https://golang.google.cn/dl/</a> 下载(第一个链接是国外的官网,第二个是国内的官网,如果第一个访问不了,可以从第二个下载)。</p>
<p>下载时可以根据自己的操作系统选择相应的开发包,比如 Window、MacOS 或是 Linux 等,如下图所示:</p>
<p><img src="assets/CgqCHl-ikW2AdldmAABgiiXVyCo654.png" alt="png" /></p>
<h4>Windows MSI 下安装</h4>
<p>MSI 安装的方式比较简单,在 Windows 系统上推荐使用这种方式。现在的操作系统基本上都是 64 位的,所以选择 64 位的 go1.15.windows-amd64.msi 下载即可,如果操作系统是 32 位的,选择 go1.15.windows-386.msi 进行下载。</p>
<p>下载后双击该 MSI 安装文件按照提示一步步地安装即可。在默认情况下Go 语言开发工具包会被安装到 c:\Go 目录,你也可以在安装过程中选择自己想要安装的目录。</p>
<p>假设安装到 c:\Go 目录,安装程序会自动把 c:\Go\bin 添加到你的 PATH 环境变量中,如果没有的话,你可以通过系统 -&gt; 控制面板 -&gt; 高级 -&gt; 环境变量选项来手动添加。</p>
<h4>Linux 下安装</h4>
<p>Linux 系统同样有 32 位和 64 位,你可以根据你的 Linux 操作系统选择相应的压缩包,它们分别是 go1.15.linux-386.tar.gz 和 go1.15.linux-amd64.tar.gz。</p>
<p>下载成功后,需要先进行解压,假设你下载的是 go1.15.linux-amd64.tar.gz在终端通过如下命令即可解压</p>
<pre><code>sudo tar -C /usr/local -xzf go1.15.linux-amd64.tar.gz
</code></pre>
<p>输入后回车,然后输入你的电脑密码,即可解压到 /usr/local 目录,然后把 /usr/local/go/bin 添加到 PATH 环境变量中,就可以使用 Go 语言开发工具包了。</p>
<p>把下面这段添加到 /etc/profile 或者 $HOME/.profile 文件中,保存后退出即可成功添加环境变量。</p>
<pre><code>export PATH=$PATH:/usr/local/go/bin
</code></pre>
<h4>macOS 下安装</h4>
<p>如果你的操作系统是 macOS可以采用 PKG 安装包。下载 go1.15.darwin-amd64.pkg 后,双击按照提示安装即可。安装成功后,路径 /usr/local/go/bin 应该已经被添加到了 PATH 环境变量中,如果没有的话,你可以手动添加,和上面 Linux 的方式一样,把如下内容添加到 /etc/profile 或者 $HOME/.profile 文件保存即可。</p>
<pre><code>export PATH=$PATH:/usr/local/go/bin
</code></pre>
<h4>安装测试</h4>
<p>以上都安装成功后,你可以打开终端或者命令提示符,输入 go version 来验证 Go 语言开发工具包是否安装成功。如果成功的话,会打印出 Go 语言的版本和系统信息,如下所示:</p>
<pre><code>$ go version
go version go1.15 darwin/amd64
</code></pre>
<h3>环境变量设置</h3>
<p>Go 语言开发工具包安装好之后,它的开发环境还没有完全搭建完成,因为还有两个重要的环境变量没有设置,它们分别是 GOPATH 和 GOBIN。</p>
<ul>
<li><strong>GOPATH</strong>:代表 Go 语言项目的工作目录,在 Go Module 模式之前非常重要,现在基本上用来存放使用 go get 命令获取的项目。</li>
<li><strong>GOBIN</strong>:代表 Go 编译生成的程序的安装目录,比如通过 go install 命令,会把生成的 Go 程序安装到 GOBIN 目录下,以供你在终端使用。</li>
</ul>
<p>假设工作目录为 /Users/flysnow/go你需要把 GOPATH 环境变量设置为 /Users/flysnow/go把 GOBIN 环境变量设置为 $GOPATH/bin。</p>
<p>在 Linux 和 macOS 下,把以下内容添加到 /etc/profile 或者 $HOME/.profile 文件保存即可。</p>
<pre><code>export GOPATH=/Users/flysnow/go
export GOBIN=$GOPATH/bin
</code></pre>
<p>在 Windows 操作系统中,则通过控制面板 -&gt; 高级 -&gt; 环境变量选项添加这两个环境变量即可。</p>
<h3>项目结构</h3>
<p>采用 Go Module 的方式,可以在任何位置创建你的 Go 语言项目。在整个专栏中,我都会使用这种方式演示 Go 语言示例,现在你先对 Go Module 项目结构有一个大概了解,后面的课时我会详细地介绍 Go Module。</p>
<p>假设你的项目位置是 /Users/flysnow/git/gotour打开终端输入如下命令切换到该目录下</p>
<pre><code>$ cd /Users/flysnow/git/gotour
</code></pre>
<p>然后再执行如下命令创建一个 Go Module 项目:</p>
<pre><code>$ go mod init
</code></pre>
<p>执行成功后,会生成一个 go.mod 文件。然后在当前目录下创建一个 main.go 文件,这样整个项目目录结构是:</p>
<pre><code>gotour
├── go.mod
├── lib
└── main.go
</code></pre>
<p>其中 main.go 是整个项目的入口文件,里面有 main 函数。lib 目录是项目的子模块,根据项目需求可以新建很多个目录作为子模块,也可以继续嵌套为子模块的子模块。</p>
<h3>编译发布</h3>
<p>完成了你的项目后,可以编译生成可执行文件,也可以把它发布到 $GOBIN 目录以供在终端使用。以“Hello 世界”为例,在项目根目录输入以下命令,即可编译一个可执行文件。</p>
<pre><code>$ go build ./ch01/main.go
</code></pre>
<p>回车执行后会在当前目录生成 main 可执行文件,现在,我们来测试下它是否可用。</p>
<pre><code>$ ./main
Hello, 世界
</code></pre>
<p>如果成功打印出“Hello, 世界”,证明程序成功生成。</p>
<p>以上生成的可执行文件在当前目录,也可以把它安装到 $GOBIN 目录或者任意位置,如下所示:</p>
<pre><code>$ go install ./ch01/main.go
</code></pre>
<p>使用 go install 命令即可,现在你在任意时刻打开终端,输入 main 回车都会打印出“Hello, 世界”,是不是很方便!</p>
<h3>跨平台编译</h3>
<p>Go 语言开发工具包的另一强大功能就是可以跨平台编译。什么是跨平台编译呢?就是你在 macOS 开发,可以编译 Linux、Window 等平台上的可执行程序,这样你开发的程序,就可以在这些平台上运行。也就是说,你可以选择喜欢的操作系统做开发,并跨平台编译成需要发布平台的可执行程序即可。</p>
<p>Go 语言通过两个环境变量来控制跨平台编译,它们分别是 GOOS 和 GOARCH 。</p>
<ul>
<li><strong>GOOS</strong>:代表要编译的目标操作系统,常见的有 Linux、Windows、Darwin 等。</li>
<li><strong>GOARCH</strong>:代表要编译的目标处理器架构,常见的有 386、AMD64、ARM64 等。</li>
</ul>
<p>这样通过组合不同的 GOOS 和 GOARCH就可以编译出不同的可执行程序。比如我现在的操作系统是 macOS AMD64 的,我想编译出 Linux AMD64 的可执行程序,只需要执行 go build 命令即可,如以下代码所示:</p>
<pre><code>$ GOOS=linux GOARCH=amd64 go build ./ch01/main.go
</code></pre>
<p>关于 GOOS 和 GOARCH 更多的组合,参考<a href="https://golang.org/doc/install/source#environment">官方文档</a>的 $GOOS and $GOARCH 这一节即可。</p>
<h3>Go 编辑器推荐</h3>
<p>好的编辑器可以提高开发的效率,这里我推荐两款目前最流行的编辑器。</p>
<p>第一款是 Visual Studio Code + Go 扩展插件,可以让你非常高效地开发,通过官方网站 <a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a> 下载使用。</p>
<p>第二款是老牌 IDE 公司 JetBrains 推出的 Goland所有插件已经全部集成更容易上手并且功能强大新手老手都适合你可以通过官方网站 <a href="https://www.jetbrains.com/go/">https://www.jetbrains.com/go/</a> 下载使用。</p>
<h3>总结</h3>
<p>这节课中你学到了如何写第一个 Go 语言程序,并且搭建好了 Go 语言开发环境,创建好了 Go 语言项目,同时也下载好了 IDE 严阵以待,那么现在我就给你留个<strong>小作业</strong></p>
<blockquote>
<p>改编示例“Hello 世界”的代码,打印出自己的名字。</p>
</blockquote>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/22 讲通关 Go 语言-完/00 开篇词 Go 为开发者的需求设计,带你实现高效工作.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/22 讲通关 Go 语言-完/02 数据类型:你必须掌握的数据类型有哪些?.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70996dab8d4a3d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>