golang学習ノート

13276 ワード

文書ディレクトリ
  • go環境
  • の構成
  • goland(IDE)ショートカット
  • インポートパッケージ
  • 集合インポートパケットデータ
  • 関数
  • 関数指定戻り値
  • 関数値指定戻りデータ型
  • 閉パッケージ
  • 変数
  • 変数タイプ設定
  • 定義変数
  • 変数初期化付与
  • 変数タイプ
  • 特殊演算
  • タイプ交換
  • 取得変数
  • 定数定義
  • サイクル
  • 基本forサイクル(C++のforと同じ)
  • 初期値およびデータ変化モジュールは、(C++のwhileと同じ)
  • を書き込まなくてもよい.
  • デッドサイクル
  • rangeと配列を組み合わせた
  • 判断
  • switch - case
  • 遅延関数
  • ポインタ
  • 構造体
  • 構造体ポインタ
  • goにはクラスの説はないが,構造体について関数法の定義
  • を行うことができる.
  • インタフェース
  • 配列slice
  • スライス関連概念
  • キー名マッピング
  • キー名の要素を削除する
  • キー名の要素が
  • 存在するかどうかを確認します.
  • 異常処理
  • 書き込みファイル
  • 上書き
  • 追加書き
  • Linux
  • ssh接続サーバ
  • shellコマンド
  • を実行
  • httpプロトコルに基づくAPIインタフェース実装
  • go環境の構成
  • 解凍goパッケージ
  • GOPATH
  • の構成
  • パケットgolang.org/x/net/context --> github.com/golang/net/context
  • をダウンロードする必要がある場合
    goland(IDE)ショートカット
    機能
    操作
    現在の行の削除
    ⌘⌫
    行コメント
    ⌘/
    ブロックコメント
    ⌥⌘/
    関数使用のヒント
    ⌘P
    コードチェックと迅速な修復
    ⌥⏎
    パッケージのインポート
    集合インポートパッケージデータ
    import(
        "fmt"
        "math/rand"
        …… ……
    )
    

    パッケージ名
    紹介する
    さぎょう
    fmt
    基本パッケージ
    入出力用
    math
    数学の基本パッケージ
    表の内容
    表の内容
    関数#カンスウ#
    関数名
    さぎょう
    fmt.Println(String)
    指定文字列の出力
    関数の戻り値の指定
    func    (  1,  2     ) (    1,    2     ){
        …… ……
        return
    }
    
    # example
    func add(x , y int) (y , x) {
    	return 
    }
    
    

    関数値戻りデータ型の指定
    func    (  1,  2     ) (    1   ,    2   ){
        …… ……
        return     1 ,     2
    }
    
    # example
    func add(x , y int) (int , int) {
    	return x + y , x
    }
    

    関数の戻り値タイプはfunc関数です.関数で変数を変更するのは一般的にグローバルな値に影響しないので、変更するにはポインタを渡す必要があります.これはC++と同じです.戻りデータが1つしか返さない場合は、カッコfunc ( 1, 2 ) {……}を書かなくてもいいです.
    クローズドパッケージ
    関数の戻り値は関数です.
    原理:関数にサブ関数がコールバックされ、匿名関数として理解できます.親関数は関数に依存するため、その関数で定義された変数はメモリに常に存在し、関数を呼び出すたびに変化が発生します.
    閉パケットは、カプセル化された環境で関数を実行すると理解でき、変数を定義するたびにこの環境を格納し、この変数を使用するたびにこの閉パケットのサブ関数を実行する.
    したがって、一般的に親関数では環境定義が行われ、子関数では操作実行が行われ、2つの変数を定義すると、この2つの変数の値は相互に影響しません.
    実行の理解については、f := function()を実行親関数として、f()を実行子関数として理解することができる
    func    () func(    )      {
            1
        return func(       )      {
                2
            return    
        }
    }
    
    # example
    func function() func() {
        a := 1
        fmt.Println("                ")
        return func(){
            a ++
            fmt.Println("            ,  a        ")
        }
    }
    
    #             
    f := function()
    f()     //          
    

    閉パッケージには値入力または出力があります
    func function() func(int) int{
        a := 1
        fmt.Println("                ")
        return func(x int) int{
            a += x
            fmt.Println("               ")
            return a
        }
    }
    
    #             
    f := function()
    f(12)     //          
    

    変数#ヘンスウ#
    定義されたすべての変数が使用されます.そうしないと、エラーが発生します.
    変数タイプの設定
       1     1 ,    2     2
    
    #           ,    
       1 ,    2     
    
    # example
    x int , y int    <====>    x , y int
    

    変数の定義
    var    1 ,    2     
    
    # example
    var x , y bool
    

    変数初期化割付
    var    1 ,    2      =  1 ,  2
    
    #           
    var    1 ,    2 =  1 ,  2
    
    # example
    var x , y int = 1 , 2
    var x , y = 1 , 2
    var (
        x = 1
        y = 2
    )
    

    以下は簡潔な書き方ですが、関数外では使用できません
      1 ,   2 :=  1 ,  2
    
    # example
    x , y := 1 , 2
    

    変数のタイプ
    変数のタイプ
    意味
    デフォルト
    代表記号
    bool
    tureまたはfalseを表す
    false
    %t
    string
    代表文字列
    (空)
    %s
    int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr
    整数タイプ
    0
    byte
    uint 8の別名
    0
    %d
    rune
    int32
    0
    %d
    float32 float64
    浮動小数点数
    0
    %f
    complex64 complex128
    虚数
    (0+0i)
    とくしゅえんざん
    <<           n 
    >>           n 
    

    タイプ交換
    T(v)vをタイプTに変換
    var i int = 42
    var f float64 = float64(i)
    var u uint = uint(f)
    
    
    #string int
    int,err:=strconv.Atoi(string)
    #string int64
    int64, err := strconv.ParseInt(string, 10, 64)
    #int string
    string:=strconv.Itoa(int)
    #int64 string
    string:=strconv.FormatInt(int64,10)
    

    変数の取得
    test string
    flag.StringVar(&test, "       ", "   ", "help    ")
    flag.Parse()
    //   test           
    
    

    入力パラメータのない例外の解決
    	if mip == "Error" || cip == "Error" || vip == "Error" {
    		flag.Usage()
    		return
    	}
    

    定数定義
    const   1 ,   2 =  1 ,  2
    
    #        
    

    ループ
    基本forサイクル(C++のforと同じ)
    for i :=     ; i <     ; i ++ {
        …………
    }
    
    

    初期値とデータ変化モジュールは書かなくてもよい(C++のwhileと同じ)
    for i <   {
    }
    

    デッドサイクル
    for {
    }
    

    rangeと配列で結合する
    配列全体のすべての要素を巡回し、毎回1つのデータを変数2に渡し、変数1は毎回+1になります.
    for   1,  2 := range    {
        …… ……
    }
    

    変数1は必要を記録するために使用され、書かなくてもよい.
    と判断
    if      {
    } else {
    }
    

    判断文には、次のような変数定義があります.
    if err:=test();err != nil {
    } else {
    }
    

    switch - case
    switch i {
    case " 1":
        ……
    case    ():
        ……    
    defalut:
        ……
    }
    

    ちえんかんすう
    最後に次の関数を実行します.複数のdeferを実行するときは、スタックロジックを採用し、原理は先進的に実行されます.
    defer   ()
    

    ししん
    そのゼロ値はnilです
    *           
    
    
    # example
    var i *int
    

    ではiの値はnilです.値を付けずに*iを使用すると異常が報告されます
    こうぞうたい
    カスタムデータ型として理解できます
    type      struct{
          1   
          2   
    }
    
    #     
       .  
    
    

    構造体ポインタ
          :=    { 1, 2……}
        := &     
    
    # example
    a := add{1,2}
    b := &a
    b.x     1
    
    

    goはクラスの言い方はありませんが、構造体について関数の方法の定義を行うことができます.
    構文は閉パケットで疲れ、関数の戻り値は関数です.
    func (           )    ()       {
        return       
    }
    
          :=    …………
         .   ()
    
    # example
    type Vertex struct {
    	X int
    	Y int
    }
    
    func (v *Vertex) Abs() float64 {
    	sum := v.X * v.X + v.Y * v.Y
    	return math.Sqrt(float64(sum))
    }
    
    func main()  {
    	v := Vertex{4,3}
    	fmt.Println(v.Abs())
    }
    

    カスタム構造体だけでなく、データ型も定義できますが、名前を変更する必要があります.
    type Vertex float
    
    func (v Vertex) Abs() float64 {
    	return math.Sqrt(float64(v))
    }
    
    

    インタフェース
    インタフェースタイプは、メソッドのセットによって定義される集合です.インタフェースタイプの値は、これらのメソッドを実装する任意の値を格納することができる.ただし,インタフェース内のメソッドの具体的な内容を完了する必要はない.
    type     interface{
           ()      
    }
    
    

    配列slice
    Null値nil
    #     
        []    
    
    # make        
        := make([]     , len    , cap   )
    
    #      
        = append(   , 1, 2)
    

    lenデフォルトは0、capデフォルトは0
    スライス関連概念
    lenはsliceの実際の要素の個数を表します.Capは現在のsliceの容量を表します
    lenの長さが足りない場合は、直接データを容量に格納することができ、初期設定容量に達すると、初期容量よりも小さくない新しい容量が追加され、追加された容量に上限がありません.
  • 原則:cap>=len
  • capは偶数
  • に違いない
  • capは初期capと同じか>=(cap初期値*2)
  • キー名マッピング
    普通はmakeと連用して、これはデータがあることを要求しません
        = make(map[    ]    )
    
    #      
       [    ] =        
    

    主な役割は配列のキー名(下付き)をカスタマイズすることです.
    データがあれば
         = map[    ]    {
           1 : { 1 ,  2}
           2 : { 1 ,  2}
    }
    

    キー名の要素を削除
    delete(  ,  )
    

    キー名の要素が存在するかどうかを確認します
        ,        :=    [  ]
        ,        =    [  ]
    

    例外処理
    if err := buildMha() ; err != nil {
        //     ,    
    	log.Panic(err)
    
    	//       
    	log.Fatal(err)
    }
    

    ファイルを書く
    上書き
        err := ioutil.WriteFile("test.txt", []byte("Hi
    "), 0666) if err != nil { log.Fatal(err) }

    追加書き
    func myWrite(config string, word ...string) error {
    	for _, i := range word {
    		f, err := os.OpenFile(config, os.O_WRONLY, 0644)
    		if err != nil {
    			fmt.Println("cacheFileList.yml file create failed. err: " + err.Error())
    			return errors.New(i)
    		} else {
    			//           
    			n, _ := f.Seek(0, os.SEEK_END)
    			//              
    			_, err = f.WriteAt([]byte(i+"
    "), n) } _ = f.Close() if err != nil { fmt.Println("cacheFileList.yml file writed failed. err: " + err.Error()) return errors.New(i) } } return nil }

    Linux
    ssh接続サーバ
    func connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) {
    	var (
    		auth         []ssh.AuthMethod
    		addr         string
    		clientConfig *ssh.ClientConfig
    		client       *ssh.Client
    		config       ssh.Config
    		session      *ssh.Session
    		err          error
    	)
    	// get auth method ,          
    	auth = make([]ssh.AuthMethod, 0)
    	if key == "" {
    		auth = append(auth, ssh.Password(password))
    	} else {
    		pemBytes, err := ioutil.ReadFile(key)
    		if err != nil {
    			return nil, err
    		}
    
    		var signer ssh.Signer
    		if password == "" {
    			signer, err = ssh.ParsePrivateKey(pemBytes)
    		} else {
    			signer, err = ssh.ParsePrivateKeyWithPassphrase(pemBytes, []byte(password))
    		}
    		if err != nil {
    			return nil, err
    		}
    		auth = append(auth, ssh.PublicKeys(signer))
    	}
    
    	if len(cipherList) == 0 {
    		config = ssh.Config{
    			Ciphers: []string{"aes128-ctr", "aes192-ctr",
    				"aes256-ctr", "[email protected]", "arcfour256",
    				"arcfour128", "aes128-cbc", "3des-cbc", "aes192-cbc", "aes256-cbc"},
    		}
    	} else {
    		config = ssh.Config{
    			Ciphers: cipherList,
    		}
    	}
    
    	clientConfig = &ssh.ClientConfig{
    		User:    user,
    		Auth:    auth,
    		Timeout: 30 * time.Second,
    		Config:  config,
    		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
    			return nil
    		},
    	}
    
    	// ssh   
    	addr = fmt.Sprintf("%s:%d", host, port)
    
    	if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
    		return nil, err
    	}
    
    	// create session
    	if session, err = client.NewSession(); err != nil {
    		return nil, err
    	}
    
    	modes := ssh.TerminalModes{
    		ssh.ECHO:          0,     // disable echoing
    		ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
    		ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    	}
    
    	if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
    		return nil, err
    	}
    
    	return session, nil
    }
    const (
    	username = "root"
    	password = ""
    	key      = "/root/.ssh/id_rsa"
    	port     = 22
    )
    
    func sshDoShell(ip string, cmd string) error{
    	ciphers := []string{}
    	session, err := connect(username, password, ip, key, port, ciphers)
    
    	if err != nil {
    		fmt.Println("   ", ip, "   ")
    		log.Fatal(err)
    	}
    	
    	defer func() {
    		if err := session.Close(); err != nil {
    			// log etc
    		}
    	}()
    
    	session.Stdout = os.Stdout
    	session.Stderr = os.Stderr
    
    	err = session.Run(cmd)
    	if err != nil{
    		return errors.New(err.Error())
    	}
    
    	return nil
    }
    

    shellコマンドの実行
    func myCmd(bash string, shell ...string) error {
    	contentArray := make([]string, 0, 5)
    	cmd := exec.Command(bash, shell...)
    
    	stdout, err := cmd.StdoutPipe()
    	if err != nil {
    		fmt.Println(cmd.Stderr, "error=>", err.Error())
    	}
    
    	_ = cmd.Start()
    
    	reader := bufio.NewReader(stdout)
    
    	contentArray = contentArray[0:0]
    	var index int
    	//               
    	for {
    		line, err2 := reader.ReadString('
    ') if err2 != nil || io.EOF == err2 { break } fmt.Print(line) index++ contentArray = append(contentArray, line) } err = cmd.Wait() if err != nil { fmt.Printf("Execute Shell %s: ", shell) return errors.New("failed with error:"+err.Error()) } return nil }

    httpプロトコルに基づくAPIインタフェースの実装
    var ListenSig  = make(chan int) 
    
    type Route struct {
    	Name        string
    	Method      string
    	Pattern     string
    	HandlerFunc http.HandlerFunc
    }
    
    type Routes []Route
    
    //       
    func Logger(inner http.Handler, name string) http.Handler {
    	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    		start := time.Now()
    		inner.ServeHTTP(w, r)
    
    		File.WriteAccessLog(r.Method+"\t"+r.RequestURI+"\t"+name+"\t"+time.Since(start).String())
    	})
    }
    
    //       
    func NewRouter() *mux.Router {
    	router := mux.NewRouter().StrictSlash(true)
    	for _, route := range routes {
    		var handler http.Handler
    		handler = route.HandlerFunc
    		handler = Logger(handler, route.Name)
    		router.
    			Methods(route.Method).
    			Path(route.Pattern).
    			Name(route.Name).
    			Handler(handler)
    	}
    
    	return router
    }
    
    var routes = Routes{
    	//            
    	Route{
    		"GetInfo",
    		"GET",
    		"/monitor/info",
    		ReturnMonitorInfo,
    	},
    
    	//            
    	Route{
    		"MonitorCollect",
    		"POST",
    		"/monitor/collect",
    		PostMonitorInfo,
    	},
    }
    
    //         
    func PostMonitorInfo(w http.ResponseWriter, r *http.Request) {
    
    }
    
    func ReturnMonitorInfo(w http.ResponseWriter, r *http.Request) {
    
    }
    
    //   api  ,port       
    func StartApi(port string) {
    	router := NewRouter()
    	File.WriteErrorLog(http.ListenAndServe(":"+port, router).Error())
    	ListenSig