日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

golang之pkg(包)

發(fā)布時間:2023/12/19 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 golang之pkg(包) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、概述

  Golang擁有超過100個標(biāo)準(zhǔn)包(可用go list std |wc -l查看)

  任何包系統(tǒng)設(shè)計的目的都是簡化大型程序的設(shè)計和維護(hù)工作,通過將一組相關(guān)的特性放進(jìn)一個獨立的模塊以便于理解和更新,在每個模塊更新的同時保持和程序中其他模塊的相對獨立,這種模塊化的特性允許每個包能被其他的不同項目共享和重用,在項目范圍內(nèi)、全局范圍內(nèi)的復(fù)用;

  每個包一般都定義了一個不同的名字空間用于它內(nèi)部的每個標(biāo)識符的訪問。 每個名字空間關(guān)聯(lián)到一個特定的包, 讓我們給類型、 函數(shù)等選擇簡短明了的名字, 這樣可以避免在我們使用它們的時候減少和其它部分名字的沖突。

  每個包還通過控制包內(nèi)名字的可見性和是否導(dǎo)出來實現(xiàn)封裝特性。 通過限制包成員的可見性并隱藏包API的具體實現(xiàn), 將允許包的維護(hù)者在不影響外部包用戶的前提下調(diào)整包的內(nèi)部實現(xiàn)。 通過限制包內(nèi)變量的可見性, 還可以強制用戶通過某些特定函數(shù)來訪問和更新內(nèi)部變量, 這樣可以保證

內(nèi)部變量的一致性和并發(fā)時的互斥約束。

二、包的使用之導(dǎo)入路徑

  每個包是由一個全局唯一的字符串所標(biāo)識的導(dǎo)入路徑定位。 出現(xiàn)在import語句中的導(dǎo)入路徑也是字符串。

import (
    "fmt"
    "math/rand"
    "encoding/json"
    "golang.org/x/net/html"
    "github.com/go-sql-driver/mysql"
)

三、包聲明:

  在每個Go源文件的開頭都必須有包聲明語句。 包聲明語句的主要目的是確定當(dāng)前包被其它包導(dǎo)入時默認(rèn)的標(biāo)識符(也稱為包名)

  例如, math/rand包的每個源文件的開頭都包含 package rand 包聲明語句, 所以當(dāng)你導(dǎo)入這個包, 你就可以用rand.Int、 rand.Float64類似的方式訪問包的成員。

  關(guān)于默認(rèn)包名一般采用導(dǎo)入路徑名的最后一段的約定也有三種例外情況。

    第一個例外, 包對應(yīng)一個可執(zhí)行程序, 也就是main包, 這時候main包本身的導(dǎo)入路徑是無關(guān)緊要的。 名字為main的包是給go build( §10.7.3) 構(gòu)建命令一個信息, 這個包編譯完之后必須調(diào)用連接器生成一個可執(zhí)行程序。

    第二個例外, 包所在的目錄中可能有一些文件名是以test.go為后綴的Go源文件( 譯注:前面必須有其它的字符, 因為以``前綴的源文件是被忽略的) , 并且這些源文件聲明的包名也是以_test為后綴名的。 這種目錄可以包含兩種包:一種普通包, 加一種則是測試的外部擴展包。

  所有以_test為后綴包名的測試外部擴展包都由go test命令獨立編譯, 普通包和測試的外部擴展包是相互獨立的。 測試的外部擴展包一般用來避免測試代碼中的循環(huán)導(dǎo)入依賴。

    第三個例外, 一些依賴版本號的管理工具會在導(dǎo)入路徑后追加版本號信息, 例如"gopkg.in/yaml.v2"。 這種情況下包的名字并不包含版本號后綴, 而是yaml?! ?/p>

   warning:如果我們想同時導(dǎo)入兩個有著名字相同的包, 例如math/rand包和crypto/rand包, 那么導(dǎo)入聲明必須至少為一個同名包指定一個新的包名以避免沖突。 這叫做導(dǎo)入包的重命名。

    import (
      "crypto/rand"
      mrand "math/rand"   // alternative name mrand avoids conflict
    )

  warning:匿名導(dǎo)入:

    import _ "image/png" // register PNG decoder

 1 // The jpeg command reads a PNG image from the standard input
 2 // and writes it as a JPEG image to the standard output.
 3 package main
 4 import (
 5   "fmt"
 6   "image"
 7   "image/jpeg"
 8   _ "image/png" // register PNG decoder
 9   "io"
10   "os"
11 ) 
12 func main() { 13   if err := toJPEG(os.Stdin, os.Stdout); err != nil { 14     fmt.Fprintf(os.Stderr, "jpeg: %v ", err) 15     os.Exit(1) 16   } 17 } 18 func toJPEG(in io.Reader, out io.Writer) error { 19   img, kind, err := image.Decode(in) //這里可能需要匿名導(dǎo)入 20   if err != nil { 21     return err 22   } 23   fmt.Fprintln(os.Stderr, "Input format =", kind) 24   return jpeg.Encode(out, img, &jpeg.Options{Quality: 95}) 25 }

  下面說說工作機制。 標(biāo)準(zhǔn)庫還提供了GIF、 PNG和JPEG等格式圖像的解碼器,用戶也可以提供自己的解碼器, 但是為了保持程序體積較小, 很多解碼器并沒有被全部包含, 除非是明確需要支持的格式。 image.Decode函數(shù)在解碼時會依次查詢支持的格式列表。

  每個格式驅(qū)動列表的每個入口指定了四件事情:格式的名稱;一個用于描述這種圖像數(shù)據(jù)開頭部分模式的字符串, 用于解碼器檢測識別;一個Decode函數(shù)用于完成解碼圖像工作;一個DecodeConfig函數(shù)用于解碼圖像的大小和顏色空間的信息。 每個驅(qū)動入口是通過調(diào)用image.RegisterFormat函數(shù)注冊, 一般是在每個格式包的init初始化函數(shù)中調(diào)用, 例如image/png包是這樣注冊的:

1 package png // image/png
2 func Decode(r io.Reader) (image.Image, error)
3 func DecodeConfig(r io.Reader) (image.Config, error)
4 func init() {
5   const pngHeader = "x89PNG
x1a
"
6   image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
7 }

  最終的效果是, 主程序只需要匿名導(dǎo)入特定圖像驅(qū)動包就可以用image.Decode解碼對應(yīng)格式的圖像!

四、自定義自己的包:

  包是函數(shù)和數(shù)據(jù)的集合。用 package 關(guān)鍵字定義一個包。文件名不需要與包名一致,但是你的文件夾必須要與包名字一致,這個很重要,所以為了簡單起見,名字都是一樣的。包名的約定是使用小寫字符。Go 包可以由多個文件組成,但是使用相同的;
  package 這一行。讓我們在文件 test1.go 中定義一個叫做 pkg的包。

1 ├── pkg
2 │ └── myprint.go
3 
4 //myprint.go
5 package pkg
6 import "fmt"
7 func MyPrintf(in string) {
8     fmt.Printf("%s", in)
9 }

  在main包中測試:

 1 package main 
 2 import  (
 3      "fmt"
 4      "./pkg"     //帶上路徑
 5 )
 6 
 7 func main() {
 8     pkg.MyPrinf("my pkg test")
 9     fmt.Printf("test ok")
10 }
11 
12 //測試ok
13 稍作修改:
14 package main 
15 import  (
16      "fmt"
17      "pkg"     //不帶上路徑
18 )
19 
20 func main() {
21     pkg.MyPrinf("my pkg test")
22     fmt.Printf("test ok")
23 }
24 
25 //closure.go:6:2: cannot find package "pkg" in any of:
26     /root/golang/go/src/pkg (from $GOROOT)
27     /root/src/pkg (from $GOPATH)
28 
29 # 解決辦法:將pkg包加個軟連接到$GOROOT 或$GOPATH

總結(jié)

以上是生活随笔為你收集整理的golang之pkg(包)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。