go语言基础知识整理
1.历史拒谈,只记录属于go的知识
2.安装环境可以看官网
正文
1.小知识:本地浏览器打开go文档
在终端输入 godoc -http=:9090,之后再浏览器输入地址localhost:9090即可,端口自己决定
mac下操作
export GOPATH=$HOME/goWorkSpace 将此路径设置goPath,类似环境变量的东西
cd $GOPATH/src/hello 打开这个项目
go build 编译当前路径下的go项目
./hello 运行编译好的hello项目
go install命令和go build类似,但有点区别
2.导入包 :
import "os"
同时导入多个包:
import (
"fmt"
"os"
"strings"
)
3.数据类型和结构
3.1 值类型
包括:字符串,整型,浮点型,布尔类型等
3.2变量
变量要显示的声明,编译阶段就能检查到类型的正确性
声明方式
//var 声明一个或者多个变量
var a string = "My First String"
var b,c int = 1,2
var d = true //自动推到变量的类型
var e int //没有初始值时,默认为'零值'
f := "short"
//:=声明的变量,一般用在局部变量的声明上,不作全局变量的命名
3.3 常量
支持字符,字符串,布尔和数值常量
声明常量的方式const关键字
const s string = "hello world!"
const n = 300004
const d = 3e20 / n //类型会自动推导
3.3 For循环
for 是Go中唯一的循环结构,常用的三种格式
i := 1
for i < 3{
fmt.Println(i)
i = i + 1
}
for j:=7;j<=9;j++{
fmt.Println(j)
}
for{
fmt.Println("For Loop")
break
}
3.4 if else 分支
if true{
fmt.Println("true")
}else{
fmt.Println("false")
}
if number := 6;number<0{
fmt.Println(number,"是负数")
}else if number<10{
fmt.Println("一位数")
}else{
fmt.Println("多位数")
}
3.4 switch分支
i := 2
fmt.Print(i,"is equal ")
switch i {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}
switch time.Now().Weekday(){
case time.Saturday,time.Sunday:
fmt.Println("it is the weekend")
default:
fmt.Println("it is weekday")
}
t := time.Now()
switch{
fmt.Println("Before noon")
default:
fmt.Println("After Noon")
}
3.5 数组:一个固定长度的数列
var arr [5]int //创建大小为5,元素类型int的数组,默认值都是0
fmt.Println("empty:",a) //[0,0,0,0,0]
a[4] = 100 //赋值
len(a) //数组长度
arr1 := [5]int{1,2,3,4,5} //有初始值的数组
//二维数组
var arr3 [2][3]int
for i:=0;i<2;i++{
for j:=0;j<3;j++{
arr3[i][j] = i * j
}
}
fmt.Println(arr3)
3.6 切片 slice,和数组类似,但是更加强大,是可变的数组,也是一个关键的数据类型
slice := make([]string,3) //必须用slice来初始化,申请内存
fmt.Println(slice)
s[0] = "a"
s[1] = "b"
s[2] = "c"
len(slice) //3长度
slice.append(slice,"d")
slice.append(slice,"e","f") //添加元素
//复制
c := make([]string,len(slice))
copy(c,slice) //复制一个slice的元素到另外一个slice
//截取部分元素
slice2 := slice[2,4] //slice[low:high]切片操作,不包含high的元素
//二维的切片
twoDSlice := make([][]int,3)
for i:=0;i<3;i++{
innerLen := i+1
twoDSlice[i] = make([]int,innerLen)
for j:=0;j
3.7 关联数组(字典)
m := make(map[string]int)
//一个空map,使用make创建
//赋值
m["k1"] = 7
m["k2"] = 16
len(m) //键值对数目
delete(m,"k2") //删除某个元素
_,ok := m["k2"] //ok当有值时为true,可以判断是否有值,防止nil引起的崩溃
//另外一种初始化方式
m2 := map[string]int{"k1":2,"k2":4}
3.8 Range遍历
numbers := []int{2,3,4}
sum := 0
//数组,slice的Range遍历
for index,num := range numbers{
sum += num
fmt.Println(index)
}
//map遍历
m := map[string]string{"k1":v1,"k2":v2}
for k,v := range m{
fmt.Printf("%s-->$s \n",k,v)
}
//遍历字符串
for i,word := range "Hello world!"{
fmt.Println(i,n)
}
3.9 函数
//一个返回值
func sub(a int,b int)(int){
return a-b
}
//多个返回值:其实是元组
func values(a int)(int,int){
return a,0
}
4.0 参数可变函数
7月4日
11.0 Defer:用来确保一个函数在程序结束之前执行.类似其他语言的ensure和finally
func main(){
f := createFile("/temp.defer.txt")
defer closeFile(f) //最后会执行关闭文件夹操作
writeFile(f)
}
func createFile(p string) *os.File{
fmt.Println("creating")
f,err := os.Create(p)
if err != nil{
panic(err)
}
return f
}
func writeFile(f *os.File){
fmt.Println("writing")
fmt.Fprintln(f,"data")
}
func closeFile(f *os.File){
fmt.Println("closing")
f.Close()
}
11.1 组合函数:我们经常需要程序在数据集上执行操作,比如选择满足给定条件的所有项,或者将所有的项通过一个自定义函数映射到一个新的集合上。
在某些语言中,会习惯使用泛型。Go 不支持泛型,在 Go 中,当你的程序或者数据类型需要时,通常是通过组合的方式来提供操作函数。
这是一些 strings 切片的组合函数示例。你可以使用这些例子来构建自己的函数。注意有时候,直接使用内联组合操作代码会更清晰,而不是创建并调用一个帮助函数
//获取目标字符串t出现的第一个索引位置,没有就返回-1
func Index(vs []sring,t string) int{
for i,v := range vs{
if v == t{
return i
}
}
return -1
}
func Include(vc []string,t string) bool{
return Index(vc,t) >= 0
}
func Any(vc []string,f func (string)bool) bool{
for _,v := range vc{
if f(v){
return true
}
}
return false
}
func All(vs []string,f func(string) bool) bool{
for _,v := range vs{
if !f(v){
return false
}
}
return true
}
//满足条件的元素
func Filter(vs []string,f func(string)bool) []string{
vcf := make([]string,0)
for _,v := range vs{
if f(v){
vsf = append(vsf,v)
}
}
return vsf
}
//返回一个对原始切片中所有字符串执行函数 f 后的新切片。
func Map(vs []string,f func(string)bool) []string{
vsm := make([]string,len(vs))
for i,v := range vs{
vsm[i] = f(v)
}
return vsm;
}
func main(){
var strs = []string{"peach", "apple", "pear", "plum"}
//这里试试这些组合函数。
//下面的例子都是用的匿名函数,但是你也可以使用类型正确的命名函数
fmt.Println(Index(strs, "pear"))
fmt.Println(Include(strs, "grape"))
fmt.Println(Any(strs, func(v string) bool {
return strings.HasPrefix(v, "p")
}))
fmt.Println(All(strs, func(v string) bool {
return strings.HasPrefix(v, "p")
}))
fmt.Println(Filter(strs, func(v string) bool {
return strings.Contains(v, "e")
}))
fmt.Println(Map(strs, strings.ToUpper))
}
11.2 字符串函数:操作字符串
func main(){
var p = fmt.Println
p("Contains:",strings.Contains("test","es"))
p("Count:",strings.Count("test","t"))
p("HasPrefix:",strings.HasPrefix("test","te"))
p("HasSuffix:",strings.HasSuffix("test","st"))
p("Index",strings.Index("test","s"))
p("Join:", strings.Join([]string{"a", "b"}, "-"))
p("Repeat:", strings.Repeat("a", 5))
p("Replace:", strings.Replace("foo", "o", "0", -1))
p("Replace:", strings.Replace("foo", "o", "0", 1))
p("Split:", strings.Split("a-b-c-d-e", "-"))
p("ToLower:", strings.ToLower("TEST"))
p("ToUpper:", strings.ToUpper("test"))
p()
p("Len:",len("hello"))
p("Char:","hello"[2])
}
11.3 字符串格式化
type point{
x,y int
}
func main(){
p := point{1,2}
fmt.Printf("%v \n",p) //打印了一个对象
fmt.Printf("%+v \n",p) //包括字段名一起打印出
fmt.Printf("%#v \n",p) //值的运行源代码片段
fmt.Printf("%T \n",p) //值的类型
fmt.Printf("%t \n",true) //bool值
fmt.Printf("%d \n",123)
fmt.Printf("%b \n",12) //二进制
fmtPrintf("%c \n",21)
fmt.Printf("%x \n",456) //十六进制
fmt.Printf("%f \n",889.1) //浮点数
fmt.Printf("%e \n",123400000.0)
fmt.Printf("%E \n",123400000.0) //科学计数法的形式表示
fmt.Printf("%s \n","\"string\"")
fmt.Printf("%q \n","\"string\"") //包含双引号
fmt.Printf("%x","hex") //base-16编码
fmt.Printf("%p \n",&p) //输出一个指针的值
fmt.Printf("|%6d|%6.2f| \n",12,234.0) //控制位数,不足的空格代替,默认右对齐
fmt.Printf("|%-6.2f|%-6.2f\n",1.2,123.2) //左对齐-
//控制字符串的宽度
fmt.Printf("|%6s|%6s| \n","hello","world")
//格式化返回一个字符串,不输出
s := fm.Sprintf(" a %s","string")
fmt.Println(s)
//Fprintf格式化并输出到io.Writers而不是os.Stdout
fmt.Fprintf(os.Stderr," an %s \n","error")
}
正则表达式
12.1 Go内置的正则表达式
import "regexp"
func main(){
match,_ := regexp.MatchString("p([a-z]+)ch","peach")
fmt.Println(match) //true
//优化的regexp结构
r,_ := regexp.Compile("p([a-z+]ch)")
fmt.Println(r.MatchString("peach"))
//fmt.Println(r.FindString("peach punch")) //查找匹配字符串的
fmt.Println(r.FindStringIndex("peach punch"))//得到的是匹配内容的起始和结束的下标
fmt.Println(r.FindAllString("peadch punch pinch")) //返回所有的匹配项
fmt.Println(r.FindStringSubmatchIndex("peach punch"))
//返回完全匹配和局部匹配的索引位置
fmt.Println(r.FindAllStringSubmatchIndex(
"peach punch pinch", -1))
//All对应到上面的所有函数
fmt.Println(r.Match([]byte("peach")))
r = regexp.MustCompile("p([a-z]+)ch") //Compile的变体
fmt.Println(r)
fmt.Println(r.ReplaceAllString("a peach","")) //替换
in := []byte("a peach")
out := r.ReplaceAllFunc(in,bytes.ToUpper)
fmt.Println(string(out))
//Func变量允许传递匹配内容到一个给定的函数中
}
JSON:
12.1 Go内置的JSON编码支持,包括内置或者自定义类型与json数据之间的转换
import "encoding/json"
import "fmt"
import "os"
//将使用这两个结构体来演示自定义类型的编码和解码。
type Response1 struct {
Page int
Fruits []string
}
type Response2 struct {
Page int `json:"page"`
Fruits []string `json:"fruits"` //自定义json数据键名
}
func main(){
//基本数据类型-->JSON编码
bolB,_ := json.Marshal(true)
fmt.Println(string(bolB))
intB,_ := json.Marshal(12)
fmt.Println(string(intB))
slc := []string{"1","2","3"}
slcB,_ := json.Marshal(slc)
fmt.Println(slcB)
mapD := map[string]int{"a":2,"b":1}
mapB,_ := json.Marshal(mapD)
fmt.Println(mapB)
resp1 := &Response1{
Page:1,
Fruits:[]string{"apple","peach","pear"}
}
resp1B,_ := json.MArshal(resp1)
fmt.Println(string(resp1B))
resp2 := &Response2{
Page:1,
Fruits:[]string{"apple","pear","peach"}
}
resp2B,_ := json.Marshal(resp2)
fmt.Println(resp2B)
//解码JSON数据为Go值的过程
byt := []byte(`{"num":87.2,"strs":["a","c"]}`)
var data map[string]interface{} //任意类型的值
if err := json.Unmarshal(byt,&data);err != nil{
panic(err)
}
fmt.Println(data) //打印
//取值
num := data["num"].(float64)
fmt.Println(num)
strs := data["strs"].(interface{})
str1 := strs[0].(string)
fmt.Println(str1)
//解码json值为自定义的类型
str := '{"page":1,"fruits":["apple","peach"]}'
res := &Response2{}
json.Unmarshal([]byte(str),&res)
fmt.Println(res)
fmt.Println(res.Fruits[0])
//我们经常使用 byte 和 string 作为使用标准输出时数据和 JSON 表示之间的中间值。我们也可以和os.Stdout 一样,直接将 JSON 编码直接输出至 os.Writer流中,或者作为 HTTP 响应体。
enc := json.NewEncoder(os.Stdout)
d := map[string]int{"apple":2,"peach":987}
enc.Encode(d)
}
时间
Go对时间和时间段提供了大量的支持
func main(){
now := time.Now()
fmt.Println(now) //2016-06-31 15:50:13.793654 +0000 UTC
then := time.Date(2016,11,17,20,34,58,651387237,time.UTC) //构建一个time
//取出时间的各个部分
fmt.Println(then.Year())
fmt.Println(then.Month())
fmt.Println(then.Day())
fmt.Println(then.Hour())
fmt.Println(then.Minute())
fmt.Println(then.Second())
fmt.Println(then.Nanosecond())
fmt.Println(then.Location())
fmt.Println(then.Weekday())
//比较
fmt.Println(then.Before(now))
fmt.Println(then.After(now))
fmt.Println(then.Equal(now))
diff := now.Sub(then)
fmt.Println(diff) //两个时间点的duration
fmt.Println(diff.Hours())
fmt.Println(diff.Minutes())
fmt.Println(diff.Seconds())
fmt.Println(diff.Nanoseconds())
fmt.Println(then.Add(diff)) //时间往后移
fmt.Println(then.Add(-diff)) //时间往前移
}
12.2 时间戳:获取Unix 时间的秒数,毫秒数或者微秒数
now := time.Now()
secs := now.Unix()
nanos := now.UnixNano()
fmt.Println(now)
millis := nanos / 1000000
fmt.Println(secs)
//将秒数或者毫秒数转为时间
fmt.Println(time.Unix(secs,0))
fmt.Println(time.Unix(0,nanos))
12.3 时间的格式化和解析
Go支持基于描述模板的时间格式化和解析
t := time.Now()
//按照RFC3339进行格式化
fmt.Println(t.Forma(time.RFC3339))
//时间解析格式
t1,e := time.Parse(
time.RFC3339,
"2013-12-02T22:09:12+00:00"
)
fmt.Println(t1) //2013-12-02 22:09:12 +0000 +0000
fmt.Println(t.Format("2:12PM"))
fmt.Println(t.Format("Mon Jan _2 12:22:12 2091"))
p(t.Format("3:04PM"))
p(t.Format("Mon Jan _2 15:04:05 2006"))
p(t.Format("2006-01-02T15:04:05.999999-07:00"))
form := "3 04 PM"
t2, e := time.Parse(form, "8 41 PM")
p(t2)
//Format 和 Parse 使用基于例子的形式来决定日期格式,一般你只要使用 time 包中提供的模式常量就行了,但是你也可以实现自定义模式。模式必须使用时间 Mon Jan 2 15:04:05 MST 2006来指定给定时间/字符串的格式化/解析方式。时间一定要按照如下所示:2006为年,15 为小时,Monday 代表星期几,等等。
fmt.Printf("%d-%02d-%02dT%02d:%02d:%02d-00:00\n",
t.Year(), t.Month(), t.Day(),
t.Hour(), t.Minute(), t.Second())
//对于纯数字表示的时间,你也可以使用标准的格式化字符串来提出出时间值得组成。
ansic := "Mon Jan _2 15:04:05 2006"
_, e = time.Parse(ansic, "8:41PM")
p(e)
//Parse 函数在输入的时间格式不正确是会返回一个错误。
12.3 随机数
func main(){
//rand.Intn(m),随机整数,0.0 <= n <= m
fmt.Println(rand.Intn(170),",")
fmt.Println(rand.Intn(21))
//rand.Float64() 0.0 -- 1.0
//伪随机数生成器
s1 := rand.NewSource(40)
r1 := rand.New(s1)
//如果使用相同的种子生成的随机数生成器,将会产生相同的随机数序列。
s2 := rand.NewSource(40)
r2 := rand.New(s2)
fmt.Print(r2.Intn(100), ",")
fmt.Print(r2.Intn(100))
fmt.Println()
}
12.4 数字解析:数字字符串转为数字
f,_ := strconv.ParseFloat("12.3",64) //64解析的位数
/*
ParseInt
ParseUint
Atoi //基础的10进制转换函数
//如果数字字符串不是数字,会报错
*/
12.5 URL解析
func main(){
s := "postgres://user:[email protected]:5432/path?k=v#f"
//我们将解析这个 URL 示例,它包含了一个 scheme,认证信息,主机名,端口,路径,查询参数和片段。
u, err := url.Parse(s)
if err != nil {
panic(err)
}
//解析这个 URL 并确保解析没有出错。
fmt.Println(u.Scheme)
//直接访问 scheme。
fmt.Println(u.User)
fmt.Println(u.User.Username())
p, _ := u.User.Password()
fmt.Println(p)
//User 包含了所有的认证信息,这里调用 Username和 Password 来获取独立值。
fmt.Println(u.Host)
h := strings.Split(u.Host, ":")
fmt.Println(h[0])
fmt.Println(h[1])
//Host 同时包括主机名和端口信息,如过端口存在的话,使用 strings.Split() 从 Host 中手动提取端口。
fmt.Println(u.Path)
fmt.Println(u.Fragment)
//这里我们提出路径和查询片段信息。
fmt.Println(u.RawQuery)
m, _ := url.ParseQuery(u.RawQuery)
fmt.Println(m)
fmt.Println(m["k"][0])
//要得到字符串中的 k=v 这种格式的查询参数,可以使用 RawQuery 函数。你也可以将查询参数解析为一个map。已解析的查询参数 map 以查询字符串为键,对应值字符串切片为值,所以如何只想得到一个键对应的第一个值,将索引位置设置为 [0] 就行了。
}
12.6 SHA1散列
SHA1 散列经常用生成二进制文件或者文本块的短标识。例如,git 版本控制系统大量的使用 SHA1 来标识受版本控制的文件和目录
//Go 在多个 crypto/* 包中实现了一系列散列函数。
func main() {
s := "sha1 this string"
h := sha1.New()
//产生一个散列值得方式是 sha1.New(),sha1.Write(bytes),然后 sha1.Sum([]byte{})。这里我们从一个新的散列开始。
h.Write([]byte(s))
//写入要处理的字节。如果是一个字符串,需要使用[]byte(s) 来强制转换成字节数组。
bs := h.Sum(nil)
//这个用来得到最终的散列值的字符切片。Sum 的参数可以用来在现有的字符切片追加额外的字节切片:一般不需要。
fmt.Println(s)
fmt.Printf("%x\n", bs)
//SHA1 值经常以 16 进制输出,例如在 git commit 中。使用%x 来将散列结果格式化为 16 进制字符串。
}
//输出结果
sha1 this string
cf23df2207d99a74fbe169e3eba035e633b65d94
可以使用和上面相似的方式来计算其他形式的散列值。例如,计算 MD5 散列,引入 crypto/md5 并使用md5.New()方法。
12.7 base64编码
import b64 "encoding/base64"
import "fmt"
//引入 encoding/base64 包并使用名称 b64代替默认的 base64.
func main() {
data := "abc123!?$*&()'-=@~"
//这是将要编解码的字符串。
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)
//Go 同时支持标准的和 URL 兼容的 base64 格式。编码需要使用 []byte 类型的参数,所以要将字符串转成此类型。
sDec, _ := b64.StdEncoding.DecodeString(sEnc)
fmt.Println(string(sDec))
fmt.Println()
//解码可能会返回错误,如果不确定输入信息格式是否正确,那么,你就需要进行错误检查了。
uEnc := b64.URLEncoding.EncodeToString([]byte(data))
fmt.Println(uEnc)
uDec, _ := b64.URLEncoding.DecodeString(uEnc)
fmt.Println(string(uDec))
//使用 URL 兼容的 base64 格式进行编解码。
}
标准 base64 编码和 URL 兼容 base64 编码的编码字符串存在稍许不同(后缀为 + 和 -),但是两者都可以正确解码为原始字符串。
12.8 读取文件
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
)
//读取文件需要经常进行错误检查
func check(e error) {
if e != nil {
panic(e)
}
}
func main(){
data,err := ioutil.ReadFile("/tmp/data") //读取文件内容到内存中
check(err)
fmt.Println(string(data))
b1 := make([]byte,5) //最多读取5个字节
n1,err := f.Read(b1)
check(err)
fmt,Printf("%d bytes: %s\n",n1,string(b1))
//从一个文件中已知的位置开始进行读取
o2,err := f.Seek(6,0)
check(err)
b2 := make([]byte,2)
n2,err := f.Read(b2)
check(err)
fmt.Printf("%d bytes @ %d: %s\n",n2,o2,string(b2))
//io包提供了一些帮助进行文件读取的函数,ReadAtLeast 得到一个更更好的实现。
o3,err := f.Seek(6,0)
check(err)
b3 := make([]byte,2)
n3,err := io.ReadAtLeast(f,b3,2)
check(err)
fmt.Println("%d bytes @ %d: %s \n",n3,o3,string(b3))
_,err = f.Seek(0,0)
check(err)
//缓冲的读取,性能好
r4 := bufio.NewReader(f)
b4,err := r4.Peek(5)
check(err)
fmt.Printf("5 bytes:%s \n",string(b4))
f.Close()//关闭文件
}
12.9 写文件
import (
"bufio"
"fmt"
"io/ioutil"
"os"
)
func check(e error) {
if e != nil {
panic(e)
}
}
func main(){
//写入一个字符串到文件
d1 := []byte("hello\ngo\n")
err := ioutil.WriteFile("/tmp/data",d1,0644)
check(err)
//先打开一个文件
f,err := os.Create("/tmp/data2")
check(err)
defer f.Close() //最后记得关闭文件
//写入切片
d2 := []byte{12,3,2,1,32,55}
n2,err := f.Write(d2)
check(err)
fmt.Printf("wrote %d bytes\n",n2)
n3,err := f.WriteString("writes\n")
fmt.Printf("wrote %d bytes\n",n3)
s.Sync)//将缓冲区的数据写入硬盘
//带有缓冲的写入器
w := bufio.NewWriter(f)
n4,err := w.WriteString("buffered\n")
fmt.Printf("wrote %d bytes\n",n4)
w.Flush()//确保所有的缓存操作已写入底层写入器
}
13.0 行为过滤器
import (
"bufio"
"fmt"
"os"
"strings"
)
func main(){
//带有缓冲的输入
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan(){
ucl := strings.ToUpper(scanner.Text())
fmt.Println(ucl)
}
if err := scanner.Err();err != nil{
fmt.Println(ucl)
}
//检查Scan的错误.
if err := scanner.Err();err != nil{
fmt.Fprintln(os.Stderr,"error:",err)
os.Exit(1)
}
}
13.1 命令行参数
命令行参数是指定程序运行参数的一个常见方式。例如,go run hello.go,程序 go 使用了 run 和 hello.go两个参数。
import "fmt"
import "os"
func main(){
//os.Args 提供原始命令行参数访问功能。注意,切片中的第一个参数是该程序的路径,并且 os.Args[1:]保存所有程序的的参数。
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
arg := os.Args[3]
//你可以使用标准的索引位置方式取得单个参数的值。
fmt.Println(argsWithProg)
fmt.Println(argsWithoutProg)
fmt.Println(arg)
}
13.2 命令行标志(参数)
命令行标志是命令行程序指定选项的常用方式。例如,在wc -l 中,这个 -l 就是一个命令行标志。
import "flag"
import "fmt"
//Go 提供了一个 flag 包,支持基本的命令行标志解析。我们将用这个包来实现我们的命令行程序示例。
func main() {
wordPtr := flag.String("word", "foo", "a string")
//基本的标记声明仅支持字符串、整数和布尔值选项。这里我们声明一个默认值为 "foo" 的字符串标志 word并带有一个简短的描述。这里的 flag.String 函数返回一个字符串指针(不是一个字符串值),在下面我们会看到是如何使用这个指针的。
numbPtr := flag.Int("numb", 42, "an int")
boolPtr := flag.Bool("fork", false, "a bool")
//使用和声明 word 标志相同的方法来声明 numb 和 fork 标志。
var svar string
flag.StringVar(&svar, "svar", "bar", "a string var")
//用程序中已有的参数来声明一个标志也是可以的。注意在标志声明函数中需要使用该参数的指针。
flag.Parse()
//所有标志都声明完成以后,调用 flag.Parse() 来执行命令行解析。
fmt.Println("word:", *wordPtr)
fmt.Println("numb:", *numbPtr)
fmt.Println("fork:", *boolPtr)
fmt.Println("svar:", svar)
fmt.Println("tail:", flag.Args())
//这里我们将仅输出解析的选项以及后面的位置参数。注意,我们需要使用类似 *wordPtr 这样的语法来对指针解引用,从而得到选项的实际值。
}
测试这个程序前,最好将这个程序编译成二进制文件,然后再运行这个程序
13.3 环境变量
环境变量是一个在为 Unix 程序传递配置信息的普遍方式。让我们来看看如何设置,获取并列举环境变量。
package main
import "os"
import "strings"
import "fmt"
func main() {
os.Setenv("FOO", "1")
fmt.Println("FOO:", os.Getenv("FOO"))
fmt.Println("BAR:", os.Getenv("BAR"))
//使用 os.Setenv 来设置一个键值对。使用 os.Getenv获取一个键对应的值。如果键不存在,将会返回一个空字符串。
fmt.Println()
for _, e := range os.Environ() {
pair := strings.Split(e, "=")
fmt.Println(pair[0])
}
//使用 os.Environ 来列出所有环境变量键值对。这个函数会返回一个 KEY=value 形式的字符串切片。你可以使用strings.Split 来得到键和值。这里我们打印所有的键。
}