golang学習ノート
文書ディレクトリ go環境 の構成 goland(IDE)ショートカット インポートパッケージ 集合インポートパケットデータ 関数 関数指定戻り値 関数値指定戻りデータ型 閉パッケージ 変数 変数タイプ設定 定義変数 変数初期化付与 変数タイプ 特殊演算 タイプ交換 取得変数 定数定義 サイクル 基本forサイクル(C++のforと同じ) 初期値およびデータ変化モジュールは、(C++のwhileと同じ) を書き込まなくてもよい.デッドサイクル rangeと配列を組み合わせた 判断 switch - case 遅延関数 ポインタ 構造体 構造体ポインタ goにはクラスの説はないが,構造体について関数法の定義 を行うことができる.インタフェース 配列slice スライス関連概念 キー名マッピング キー名の要素を削除する キー名の要素が 存在するかどうかを確認します.異常処理 書き込みファイル 上書き 追加書き Linux ssh接続サーバ shellコマンド を実行 httpプロトコルに基づくAPIインタフェース実装 go環境の構成解凍goパッケージ GOPATH の構成パケット をダウンロードする必要がある場合
goland(IDE)ショートカット
機能
操作
現在の行の削除
⌘⌫
行コメント
⌘/
ブロックコメント
⌥⌘/
関数使用のヒント
⌘P
コードチェックと迅速な修復
⌥⏎
パッケージのインポート
集合インポートパッケージデータ
パッケージ名
紹介する
さぎょう
fmt
基本パッケージ
入出力用
math
数学の基本パッケージ
表の内容
表の内容
関数#カンスウ#
関数名
さぎょう
fmt.Println(String)
指定文字列の出力
関数の戻り値の指定
関数値戻りデータ型の指定
関数の戻り値タイプはfunc関数です.関数で変数を変更するのは一般的にグローバルな値に影響しないので、変更するにはポインタを渡す必要があります.これはC++と同じです.戻りデータが1つしか返さない場合は、カッコ
クローズドパッケージ
関数の戻り値は関数です.
原理:関数にサブ関数がコールバックされ、匿名関数として理解できます.親関数は関数に依存するため、その関数で定義された変数はメモリに常に存在し、関数を呼び出すたびに変化が発生します.
閉パケットは、カプセル化された環境で関数を実行すると理解でき、変数を定義するたびにこの環境を格納し、この変数を使用するたびにこの閉パケットのサブ関数を実行する.
したがって、一般的に親関数では環境定義が行われ、子関数では操作実行が行われ、2つの変数を定義すると、この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)
とくしゅえんざん
タイプ交換
式
変数の取得
入力パラメータのない例外の解決
定数定義
ループ
基本forサイクル(C++のforと同じ)
初期値とデータ変化モジュールは書かなくてもよい(C++のwhileと同じ)
デッドサイクル
rangeと配列で結合する
配列全体のすべての要素を巡回し、毎回1つのデータを変数2に渡し、変数1は毎回+1になります.
変数1は必要を記録するために使用され、書かなくてもよい.
と判断
判断文には、次のような変数定義があります.
switch - case
ちえんかんすう
最後に次の関数を実行します.複数のdeferを実行するときは、スタックロジックを採用し、原理は先進的に実行されます.
ししん
そのゼロ値は
ではiの値はnilです.値を付けずに*iを使用すると異常が報告されます
こうぞうたい
カスタムデータ型として理解できます
構造体ポインタ
goはクラスの言い方はありませんが、構造体について関数の方法の定義を行うことができます.
構文は閉パケットで疲れ、関数の戻り値は関数です.
カスタム構造体だけでなく、データ型も定義できますが、名前を変更する必要があります.
インタフェース
インタフェースタイプは、メソッドのセットによって定義される集合です.インタフェースタイプの値は、これらのメソッドを実装する任意の値を格納することができる.ただし,インタフェース内のメソッドの具体的な内容を完了する必要はない.
配列slice
Null値nil
lenデフォルトは0、capデフォルトは0
スライス関連概念
lenはsliceの実際の要素の個数を表します.Capは現在のsliceの容量を表します
lenの長さが足りない場合は、直接データを容量に格納することができ、初期設定容量に達すると、初期容量よりも小さくない新しい容量が追加され、追加された容量に上限がありません.原則:cap>=len capは偶数 に違いない capは初期capと同じか>=(cap初期値*2) キー名マッピング
普通はmakeと連用して、これはデータがあることを要求しません
主な役割は配列のキー名(下付き)をカスタマイズすることです.
データがあれば
キー名の要素を削除
キー名の要素が存在するかどうかを確認します
例外処理
ファイルを書く
上書き
追加書き
Linux
ssh接続サーバ
shellコマンドの実行
httpプロトコルに基づくAPIインタフェースの実装
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の長さが足りない場合は、直接データを容量に格納することができ、初期設定容量に達すると、初期容量よりも小さくない新しい容量が追加され、追加された容量に上限がありません.
普通は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