Golang是2009年由谷歌的三位大佬(Robert Griesemer, Rob Pike, Ken Thompson)创造的一门新语言。Goalng有很多优点。比如,作为静态类型语言,Golang的依赖少,易于部署。它还支持协程并发,支持垃圾回收,可跨平台编译。Golang兼具动态语言的强大表达能力和C的执行效率,被誉为21世纪的C语言。
最近在学习Golang,为了寻找配置教程、优秀的电子书以及难度曲线适中的入门实践项目,我颇费了些功夫。趁着记忆还新鲜,我想分享一下我的学习路径以及学习资料。本文涉及Golang的安装、配置、运行以及实践项目。希望通过阅读本文,初学者们可以更快地找到适合自己的学习方向。
官网提供标准安装包,一路点击就能完成安装。
安装包的链接是https://golang.org/dl/,更多关于安装的信息见安装 Go.
(一)在终端运行
在命令行运行程序 几乎不需要配置。只要下载Golang,然后按官方建议,创建一个名为gocode的文件夹,直接在里面写代码就可以了。为了防止以后import其他包发生错误,建议把gocode文件夹放在GOPATH下。如何知道Golang的工作路径(GOPATH)在哪里呢?打开命令行,输入go env
,就能在输出里找到工作路径了(注意区别安装路径和工作路径,它们是两个不同的路径)。
下面是Golang在命令行运行时的一些常用命令:
$ mkdir foldername
$ cd foldername
$ cd ..
$ touch filename.go
$ rm filename.go
$ mv filename1.go filename2.go
$ vim filename.go
$ go run filename.go
$ go build filename.go
$ ./filename
(二)在VSCode上运行
关于如何在VSCode上配置Golang运行环境,这个Youtube视频讲得很细:How to Configure Visual Studio Code for Go?
鉴于国内可能打不开YouTube,我用文字介绍一下配置步骤:
Go Install/Update Tools
。会弹出一列单选框,点全选,然后点OK安装Shell Command: Install 'code' command in PATH
,按回车安装这样就配置完成啦!
运行go程序时,在Command Palette输入View: Toggle Integrated Terminal
,即可在VSCode内打开命令行界面。在命令行界面输入go run filename.go
,即可运行go程序。使用VSCode快捷键,可以更快地完成上述步骤,在此就不多作介绍了。
(一)语言基础
Golang是一门简捷的语言,遵循敏捷开发(Agile Development)的原则,语言本身并不难。而且Golang官网提供了相当丰富的教程和代码示例,因此入门还是相当容易的。
对于初学者,建议先看官方的入门教程,再跑跑Go by Example上的Demo熟悉一下语言特性,就差不多了。
(二)入门书籍
入门书籍我推荐build-web-application-with-golang。这本书对概念的讲解细致到位,示例代码丰富,学习曲线也很平滑,适合初学者学习理解。在开始项目实践之前,可以先快速地浏览一下这本书。建议读一读2.2 Go基础中的代码,对深入了解Go语言还是挺有帮助的。
(三)项目实践
项目实践的最终目标是制作一个属于自己的Web application。为了实现这个目标,需要循序渐进。所以我们先用Go搭建我们的第一个静态网页,然后再尝试搭建动态网页。
(1)用Go搭建静态网页
搭建静态网页,我参考的是这个教程:Serving Static Sites with Go [PDF]。
按教程做完之后,我打算把之前在JavaScript初探中写的网页移植到这里验证一下。
详细代码(点击展开)首先打开命令行,为项目创建目录。
$ mkdir to-do-list
$ cd to-do-list
除了在app.go中放置我们的代码,我们还需要创建static文件夹放置网页内容,templates文件夹放置模版。
$ touch app.go
$ mkdir -p static/stylesheets
$ touch static/example.html static/stylesheets/style.css
$ mkdir -p static/javascript
$ touch static/example.html static/javascript/main.js
$ mkdir templates
$ touch templates/layout.html templates/example.html
package main
import (
"html/template"
"log"
"net/http"
"os"
"path/filepath"
)
func main() {
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
http.HandleFunc("/", serveTemplate)
log.Println("\nWeb Server is available at http://localhost:3000/example.html")
http.ListenAndServe(":3000", nil)
}
func serveTemplate(w http.ResponseWriter, r *http.Request) {
lp := filepath.Join("templates", "layout.html")
fp := filepath.Join("templates", filepath.Clean(r.URL.Path))
// Return a 404 if the template doesn't exist
info, err := os.Stat(fp)
if err != nil {
if os.IsNotExist(err) {
http.NotFound(w, r)
return
}
}
// Return a 404 if the request is for a directory
if info.IsDir() {
http.NotFound(w, r)
return
}
tmpl, err := template.ParseFiles(lp, fp)
if err != nil {
// Log the detailed error
log.Println(err.Error())
// Return a generic "Internal Server Error" message
http.Error(w, http.StatusText(500), 500)
return
}
if err := tmpl.ExecuteTemplate(w, "layout", nil); err != nil {
log.Println(err.Error())
http.Error(w, http.StatusText(500), 500)
}
}
body {
font-family: "Source Han Sans", "San Francisco", "PingFang SC", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif;
font-size: 14px;
color: #333;
}
a {
text-decoration: none;
color: #f66;
transition-property: color;
transition-duration: .2s;
transition-timing-function: ease-in-out;
}
a:hover {
color: #333;
}
p {
margin: 1em 0;
}
p:empty {
height: 1.5em;
}
main {
margin: 0 5em;
max-width: 60em;
}
h1 {
margin: 1em 0;
font-size: 24px;
font-weight: 300;
}
textarea, article {
width: 100%;
height: 12em;
margin: 2em 0;
padding: .5em;
overflow-y: scroll;
border: 1px solid #999;
border-radius: 2px;
line-height: 1.5;
text-align: justify;
text-justify: inter-ideograph;
}
textarea {
height: 9em;
font-size: 14px;
font-family: "Source Han Sans", "San Francisco", "PingFang SC", "Hiragino Sans GB", "Droid Sans Fallback", "Microsoft YaHei", sans-serif;
color: #333;
}
article {
cursor: pointer;
}
button {
background: #fff;
border: 1px solid #ccc;
border-radius: 2px;
line-height: 1;
padding: .5em;
color: #666;
transition-property: color, background, border;
transition-duration: .2s;
transition-timing-function: ease-in-out;
}
button[id] {
border: 1px solid #999;
color: #333;
cursor: pointer;
}
button[id]:hover {
background: #666;
border-color: #666;
color: #fff;
}
::selection {
color: #fff;
background: #666;
}
::-moz-selection {
color: #fff;
background: #666;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
}
th, td {
padding: 5px;
}
th {
text-align: left;
}
"use strict";
var Items = {
name: "",
isCheck: "false",
isDelete: "false"
};
var objArray = [];
var subArray = [];
var submit_flag = true;
var delete_flag = true;
function addElement() {
submit_flag = true;
var item = Object.create(Items);
var v = document.getElementById("myTextarea").value;
item.name = v
objArray.push(item);
var body = '# Name '
for (var i = 0; i < objArray.length; i++) {
var index = i+1;
body += '';
body += '' + index.toString(10) + ' ';
//body += '' + '' + ' ';
body += '' + objArray[i].name + ' ';
//body += '' + objArray[i].isDelete + ' ';
//body += '' + '' + ' ';
body += ' ';
}
body += '