Go基礎知識整理

go語言基礎知識整理

1.歷史拒談,只記錄屬于go的知識
2.安裝環(huán)境可以看官網(wǎng)

正文

1.小知識:本地瀏覽器打開go文檔
在終端輸入 godoc -http=:9090,之后再瀏覽器輸入地址localhost:9090即可,端口自己決定

mac下操作
export GOPATH=$HOME/goWorkSpace 將此路徑設置goPath,類似環(huán)境變量的東西

cd $GOPATH/src/hello 打開這個項目
go build 編譯當前路徑下的go項目
./hello 運行編譯好的hello項目
go install命令和go build類似,但有點區(qū)別

2.導入包 :
import "os"

同時導入多個包:
import (
"fmt"
"os"
"strings"
)

3.數(shù)據(jù)類型和結構
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 常量

支持字符,字符串,布爾和數(shù)值常量

聲明常量的方式const關鍵字

const s string = "hello world!"
const n = 300004
const d = 3e20 / n //類型會自動推導

3.3 For循環(huán)

for 是Go中唯一的循環(huán)結構,常用的三種格式

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,"是負數(shù)")
}else if number<10{
    fmt.Println("一位數(shù)")
}else{
    fmt.Println("多位數(shù)")
}

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 數(shù)組:一個固定長度的數(shù)列

var arr [5]int //創(chuàng)建大小為5,元素類型int的數(shù)組,默認值都是0
fmt.Println("empty:",a) //[0,0,0,0,0]

a[4] = 100 //賦值
len(a)       //數(shù)組長度

arr1 := [5]int{1,2,3,4,5} //有初始值的數(shù)組

//二維數(shù)組

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,和數(shù)組類似,但是更加強大,是可變的數(shù)組,也是一個關鍵的數(shù)據(jù)類型

    slice := make([]string,3) //必須用slice來初始化,申請內(nèi)存
    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<innerLen;j++{
            twoDSlice[i][j] = i + j
        }
    }
    fmt.Println("twoDSlice:",twoDSlice);
    

3.7 關聯(lián)數(shù)組(字典)

m := make(map[string]int)
//一個空map,使用make創(chuàng)建

//賦值
m["k1"] = 7
m["k2"] = 16

len(m) //鍵值對數(shù)目
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

//數(shù)組,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 函數(shù)

//一個返回值
func sub(a int,b int)(int){
    return a-b
}

//多個返回值:其實是元組
func values(a int)(int,int){
    return a,0
}

4.0 參數(shù)可變函數(shù)



7月4日

11.0 Defer:用來確保一個函數(shù)在程序結束之前執(zhí)行.類似其他語言的ensure和finally

func main(){
    f := createFile("/temp.defer.txt")
    defer closeFile(f) //最后會執(zhí)行關閉文件夾操作
    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 組合函數(shù):我們經(jīng)常需要程序在數(shù)據(jù)集上執(zhí)行操作,比如選擇滿足給定條件的所有項,或者將所有的項通過一個自定義函數(shù)映射到一個新的集合上。

在某些語言中,會習慣使用泛型。Go 不支持泛型,在 Go 中,當你的程序或者數(shù)據(jù)類型需要時,通常是通過組合的方式來提供操作函數(shù)。

這是一些 strings 切片的組合函數(shù)示例。你可以使用這些例子來構建自己的函數(shù)。注意有時候,直接使用內(nèi)聯(lián)組合操作代碼會更清晰,而不是創(chuàng)建并調(diào)用一個幫助函數(shù)

//獲取目標字符串t出現(xiàn)的第一個索引位置,沒有就返回-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
}

//返回一個對原始切片中所有字符串執(zhí)行函數(shù) 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"}
    //這里試試這些組合函數(shù)。

//下面的例子都是用的匿名函數(shù),但是你也可以使用類型正確的命名函數(shù)
    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 字符串函數(shù):操作字符串

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) //浮點數(shù)
    fmt.Printf("%e \n",123400000.0)
    fmt.Printf("%E \n",123400000.0) //科學計數(shù)法的形式表示
    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) //控制位數(shù),不足的空格代替,默認右對齊
    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內(nèi)置的正則表達式

import "regexp"

func main(){
    match,_ := regexp.MatchString("p([a-z]+)ch","peach")
    fmt.Println(match) //true
    
    //優(yōu)化的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"))//得到的是匹配內(nèi)容的起始和結束的下標
    
    fmt.Println(r.FindAllString("peadch punch pinch")) //返回所有的匹配項
    
     fmt.Println(r.FindStringSubmatchIndex("peach punch"))
    //返回完全匹配和局部匹配的索引位置
    
    fmt.Println(r.FindAllStringSubmatchIndex(
        "peach punch pinch", -1))
    //All對應到上面的所有函數(shù)
    
    fmt.Println(r.Match([]byte("peach")))
    
    r = regexp.MustCompile("p([a-z]+)ch") //Compile的變體
    fmt.Println(r)
    
    fmt.Println(r.ReplaceAllString("a peach","<fruit>")) //替換
    
    in := []byte("a peach")
    out := r.ReplaceAllFunc(in,bytes.ToUpper)
    fmt.Println(string(out))
    //Func變量允許傳遞匹配內(nèi)容到一個給定的函數(shù)中
}


JSON:

12.1 Go內(nèi)置的JSON編碼支持,包括內(nèi)置或者自定義類型與json數(shù)據(jù)之間的轉(zhuǎn)換

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數(shù)據(jù)鍵名
}

func main(){
    //基本數(shù)據(jù)類型-->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數(shù)據(jù)為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])
    
    //我們經(jīng)常使用 byte 和 string 作為使用標準輸出時數(shù)據(jù)和 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 時間的秒數(shù),毫秒數(shù)或者微秒數(shù)

now := time.Now()
secs := now.Unix()
nanos := now.UnixNano()
fmt.Println(now)


millis := nanos / 1000000

fmt.Println(secs)

//將秒數(shù)或者毫秒數(shù)轉(zhuǎn)為時間

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 包中提供的模式常量就行了,但是你也可以實現(xiàn)自定義模式。模式必須使用時間 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())
    //對于純數(shù)字表示的時間,你也可以使用標準的格式化字符串來提出出時間值得組成。

    ansic := "Mon Jan _2 15:04:05 2006"
    _, e = time.Parse(ansic, "8:41PM")
    p(e)
    //Parse 函數(shù)在輸入的時間格式不正確是會返回一個錯誤。
    

12.3 隨機數(shù)

func main(){

    //rand.Intn(m),隨機整數(shù),0.0 <= n <= m
    fmt.Println(rand.Intn(170),",")
    fmt.Println(rand.Intn(21))
    
    //rand.Float64() 0.0 -- 1.0
    
    //偽隨機數(shù)生成器
    s1 := rand.NewSource(40)
    r1 := rand.New(s1)
    
    //如果使用相同的種子生成的隨機數(shù)生成器,將會產(chǎn)生相同的隨機數(shù)序列。
    s2 := rand.NewSource(40)
    r2 := rand.New(s2)
    fmt.Print(r2.Intn(100), ",")
    fmt.Print(r2.Intn(100))
    fmt.Println()
    
}

12.4 數(shù)字解析:數(shù)字字符串轉(zhuǎn)為數(shù)字

f,_ := strconv.ParseFloat("12.3",64) //64解析的位數(shù)
/*
    ParseInt
    ParseUint
    Atoi //基礎的10進制轉(zhuǎn)換函數(shù)
    
    //如果數(shù)字字符串不是數(shù)字,會報錯
*/

12.5 URL解析

func main(){
    s := "postgres://user:pass@host.com:5432/path?k=v#f"
    //我們將解析這個 URL 示例,它包含了一個 scheme,認證信息,主機名,端口,路徑,查詢參數(shù)和片段。

    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 包含了所有的認證信息,這里調(diào)用 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 這種格式的查詢參數(shù),可以使用 RawQuery 函數(shù)。你也可以將查詢參數(shù)解析為一個map。已解析的查詢參數(shù) map 以查詢字符串為鍵,對應值字符串切片為值,所以如何只想得到一個鍵對應的第一個值,將索引位置設置為 [0] 就行了。
}

12.6 SHA1散列
SHA1 散列經(jīng)常用生成二進制文件或者文本塊的短標識。例如,git 版本控制系統(tǒng)大量的使用 SHA1 來標識受版本控制的文件和目錄


//Go 在多個 crypto/* 包中實現(xiàn)了一系列散列函數(shù)。

func main() {
    s := "sha1 this string"

    h := sha1.New()
    //產(chǎn)生一個散列值得方式是 sha1.New(),sha1.Write(bytes),然后 sha1.Sum([]byte{})。這里我們從一個新的散列開始。

    h.Write([]byte(s))
    //寫入要處理的字節(jié)。如果是一個字符串,需要使用[]byte(s) 來強制轉(zhuǎn)換成字節(jié)數(shù)組。

    bs := h.Sum(nil)
    //這個用來得到最終的散列值的字符切片。Sum 的參數(shù)可以用來在現(xiàn)有的字符切片追加額外的字節(jié)切片:一般不需要。

    fmt.Println(s)
    fmt.Printf("%x\n", bs)
    //SHA1 值經(jīng)常以 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 類型的參數(shù),所以要將字符串轉(zhuǎn)成此類型。

    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"
)

//讀取文件需要經(jīng)常進行錯誤檢查
func check(e error) {
    if e != nil {
        panic(e)
    }
}


func main(){
    data,err := ioutil.ReadFile("/tmp/data") //讀取文件內(nèi)容到內(nèi)存中
    check(err)
    fmt.Println(string(data))
    
    b1 := make([]byte,5) //最多讀取5個字節(jié)
    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包提供了一些幫助進行文件讀取的函數(shù),ReadAtLeast 得到一個更更好的實現(xiàn)。

    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)//將緩沖區(qū)的數(shù)據(jù)寫入硬盤
    
    //帶有緩沖的寫入器
    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 命令行參數(shù)
命令行參數(shù)是指定程序運行參數(shù)的一個常見方式。例如,go run hello.go,程序 go 使用了 run 和 hello.go兩個參數(shù)。

import "fmt"
import "os"

func main(){

//os.Args 提供原始命令行參數(shù)訪問功能。注意,切片中的第一個參數(shù)是該程序的路徑,并且 os.Args[1:]保存所有程序的的參數(shù)。
    argsWithProg := os.Args
    argsWithoutProg := os.Args[1:]

    arg := os.Args[3]
    //你可以使用標準的索引位置方式取得單個參數(shù)的值。

    fmt.Println(argsWithProg)
    fmt.Println(argsWithoutProg)
    fmt.Println(arg)
}


13.2 命令行標志(參數(shù))

命令行標志是命令行程序指定選項的常用方式。例如,在wc -l 中,這個 -l 就是一個命令行標志。

import "flag"
import "fmt"
//Go 提供了一個 flag 包,支持基本的命令行標志解析。我們將用這個包來實現(xiàn)我們的命令行程序示例。

func main() {

    wordPtr := flag.String("word", "foo", "a string")
    //基本的標記聲明僅支持字符串、整數(shù)和布爾值選項。這里我們聲明一個默認值為 "foo" 的字符串標志 word并帶有一個簡短的描述。這里的 flag.String 函數(shù)返回一個字符串指針(不是一個字符串值),在下面我們會看到是如何使用這個指針的。

    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")
    //用程序中已有的參數(shù)來聲明一個標志也是可以的。注意在標志聲明函數(shù)中需要使用該參數(shù)的指針。

    flag.Parse()
    //所有標志都聲明完成以后,調(diào)用 flag.Parse() 來執(zhí)行命令行解析。

    fmt.Println("word:", *wordPtr)
    fmt.Println("numb:", *numbPtr)
    fmt.Println("fork:", *boolPtr)
    fmt.Println("svar:", svar)
    fmt.Println("tail:", flag.Args())
    //這里我們將僅輸出解析的選項以及后面的位置參數(shù)。注意,我們需要使用類似 *wordPtr 這樣的語法來對指針解引用,從而得到選項的實際值。
}

測試這個程序前,最好將這個程序編譯成二進制文件,然后再運行這個程序

13.3 環(huán)境變量

環(huán)境變量是一個在為 Unix 程序傳遞配置信息的普遍方式。讓我們來看看如何設置,獲取并列舉環(huán)境變量。

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 來列出所有環(huán)境變量鍵值對。這個函數(shù)會返回一個 KEY=value 形式的字符串切片。你可以使用strings.Split 來得到鍵和值。這里我們打印所有的鍵。
}

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,679評論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,563評論 19 139
  • 引言 Go 語言這兩年在語言排行榜上的上升勢頭非常猛,Go 語言雖然是靜態(tài)編譯型語言,但是它卻擁有腳本化的語法,支...
    一縷殤流化隱半邊冰霜閱讀 33,731評論 11 90
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • 我喜歡睡懶覺,就如我喜歡玩游戲一樣。但,其實是自己找不到事做,我不喜歡看書,一看到書我頭就暈,或許是沒有遇到我喜歡...
    簡丶煌閱讀 268評論 0 0

友情鏈接更多精彩內(nèi)容