安装环境
GOROOT GOPATH
有编程基础的人开始学go时会对这两个概念很迷惑,其实:
GOROOT
是指:go的安装目录,比如说从官网下的安装包的解压目录
GOPATH
是指:工作目录,什么是工作目录?比方说新建个项目,叫test,这个目录就是工作目录
GOPATH
是GO语言使用的一个环境变量,使用绝对路径提供项目的工作目录,适合处理大量 Go语言源码、多个包组合而成的复杂工程。
关于GOPATH
设置,建议不要做全局设置而是跟随相应的项目设置。
go mod
在go1.11之后go mod
的加入使得我们写代码不用在gopath之下写了,具体做法如下:
- 1, 新建一个目录,在
GOPATH
之外,作为项目目录,cd
进去 - 2, 确保设置了
GO111MODULE="on"
和GOPROXY="https://goproxy.cn"
- 3,
go mod init “项目名”
,生成一个go.mod
- 4,
import
需要的包,执行go mod tidy
, 会自动下载包,下载到GOPATH
下的pkg目录
基础知识
开始于HelloWorld
package main //声明这是一个main包,每个go程序都应该有一个main包
import "fmt" //相当于python中的imoprt导入其他函数
func main() { // 函数的固定写法 // main函数是启动的的一个函数
fmt.Println("HelloWorld")
} // //和/**/都是注释
go语言中的包
包的概念
Go语言的代码通过包(package)组织,包类似于其它语言里的库(libraries)或者模块(modules)。一个包由位于单个目录下的一个或多个.go源代码文件组成,目录定义包的作用。每个源文件都以一条package
声明语句开始,这个例子里就是package main
,表示该文件属于哪个包,紧跟着一系列导入(import)的包,之后是存储在这个文件里的程序语句。
注意:
- 一个
Go
语言程序有且只有一个main
函数,他是Go
语言程序的入口函数,且必须属于main
包,没有或者多于一个进行Go语言
程序编译时都会报错 - 文件名与包名没有直接关系,不一定要将文件名与包名定成同一个,。
- 文件夹名与包名没有直接关系,并非需要一致,不过建议同名。
- 同一个文件夹下的文件只能有一个包名,否则编译报错。
包的引用
Go包的引入格式常见的有四种,下面以引用fmt
包为例说明:
-
标准引入:
import fmt
-
别名引入:
import myfmt fmt
省略方式的引入:import . fmt
这样就不需要加上fmt.
来调用Println
函数,相当于把fmt
加入了当前命名空间 -
单行导入:
import package
-
多行导入:
import ( "package1" "package2" )
导出
- 当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,那么使用这种形式的标识符的对象就可以被外部包的代码所使用 (像面向对象语言中的 public);
- 标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )
go语言中的函数
一个函数的声明由func
关键字、函数名、参数列表、返回值列表(这个例子里的main
函数参数列表和返回值都是空的)以及包含在大括号里的函数体组成。
一个函数一般是这样:
func name(parameter-list) (result-list) {
body
}
入门DEMO
1,使用go来实现echo命令
echo.go
package main
import (
"fmt"
"os"
)
func echo() {
var s, seq string
for i := 1; i < len(os.Args); i++ {
//println(os.Args)
s += seq + os.Args[i]
seq = " "
}
fmt.Println(s)
}
main.go
package main
func main() {
echo()
}
11:32:32 zhq@manjaro test go build .
11:35:22 zhq@manjaro test ls
echo.go hello.go main.go test
11:35:24 zhq@manjaro test ./test Hello World
Hello World
2,查找重复的行
package main
import (
"bufio"
"fmt"
"os"
)
func dup() {
counts := make(map[string]int)
input := bufio.NewScanner(os.Stdin)
for input.Scan() {
counts[input.Text()]++
}
for line, n := range counts {
if n > 1 {
fmt.Printf("%d\t%s\n", n, line)
}
}
}
使用CTRL+D来退出循环
3,简单的web程序
package main
import (
"fmt"
"log"
"net/http"
)
func web() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe("localhost:8000", nil))
}
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Println(w, "URL:", r.URL.Path)
}
13:31:40 zhq@manjaro test curl localhost:8000/hello 1 ↵
&{0xc000208000 0xc000226000 {} 0x4de4c0 false false false false 0 {0 0} 0xc00021e100 {0xc000232000 map[] false false} map[] false 0 -1 0 false false [] 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0] 0xc000230000 0} URL: /hello