LoginSignup
1
1

More than 1 year has passed since last update.

初心者がGoを学ぶときに気になったことメモ

Posted at

最近のはやりに乗って、GoとBlockchainの両方をこの動画(シリコンバレーエンジニアの酒井潤さんの「現役シリコンバレーエンジニアが教えるGoで始めるスクラッチからのブロックチェーン開発入門」https://www.udemy.com/course/go-blockchain/
)を見て勉強し始め、ここ最近終了したところなのだが、なんせbackendもblockchainもまるで初心者なもので、この動画を通してGOの理解しにくかった部分を自分なりにかみくだいてアウトプットしていこうと思う。僕のようにバックエンド完全初心者の手助けになれば幸いです

MarshalJsonって何?

MarshalJsonというのは、構造体→JSON形式に変換することらしい。
(逆にUnMarshalJsonというのは、JSON形式→構造体に変換すること)

しかし、この講座をみていると、少し不思議な書き方をしていた。

blockchain.go
type Block struct {
	timestamp    int64
	nonce        int
	previousHash [32]byte
	transactions []*Transaction
}

func (b *Block) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
          //型       //json上における名前 
		Timestamp    int64          `json:"timestamp"`
		Nonce        int            `json:"nonce"`
		PreviousHash string         `json:"previous_hash"`
		Transactions []*Transaction `json:"transactions"`
	}{        
           //入れたい値
		Timestamp:    b.timestamp,
		Nonce:        b.nonce,
		PreviousHash: fmt.Sprintf("%x", b.previousHash),
		Transactions: b.transactions,
	})
}

"encoding/json"というパッケージの中にMarshalという関数があるのに、わざわざMarshalJsonという関数をつくっている。(しかも少し複雑な書き方で)

これが何なのか調べたところ、プログラムと実際のJson内で異なる型を使いたいときがあるとき、このようにひと手間加えてMarshalJsonするらしい。

sync.Mutexという謎の型

こんな記述があった

blockchain.go

func (bc *Blockchain) SyncNeighbors() {
	bc.muxNeighbors.Lock()
	defer bc.muxNeighbors.Unlock()
	bc.SetNeighbors()
}

なんやら排他制御を行いたいときに、使うらしい。
理解してしまえば簡単だが、並列処理などで処理の衝突(当時に同じ配列を書き換える、など)を防ぐために、
Lockでその変数に鍵をかけ一つだけしか処理をできないようにし、
deferで関数の最後にUnlockをして、鍵を開けているということらしい

httpリクエストを飛ばす方法

少しできる人からしたら簡単なことだろうが、まったく知らなかったのでメモ。

// request structの作成
req, _ := http.NewRequest(
    "Post",
    "https://test",
    bytes.NewBuffer([]byte("request body"),
)
// そのheaderを指定
req.Header.Add("Content-Type", "application/json")

// クライアントを初期化
var client *http.Client = &http.Client{}
//今回の動画見る感じ、これでも行ける?
client := &http.Client{}

// そこからリクエストを飛ばす
resp, _ := client.Do(req)

// そのリスポンスをprint
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))


エンドポイントをいじりたいときは、

方法1結合
base, _ := url.Parse("https://test/mypage/")
reference, _ := url.Parse("myPicture?a=1&b=2")
endpoint := base.ResolveReference(reference).String() // URLを結合する


方法2変数名を入れる
endpoint := fmt.Sprintf("http://%s/transactions", n)

こんな感じで少しいじってやる。

flag

コマンドライン引数を指定できる。
今回だとこんな感じで、port番号とgatewayを指定していた。


func main() {
	port := flag.Uint("port", 8080, "TCP Port Number for Wallet Server")
	gateway := flag.String("gateway", "http://127.0.0.1:5000", "Blockchain Gateway")
	flag.Parse()

	app := NewWalletServer(uint16(*port), *gateway)
	app.Run()
}

また、気になったことがあれば随時更新していきます。

講義を受けている途中はちんぷんかんぷんだったが、この記事を書くにつれ頭の中でまとまって、Goを割と理解できるようになってきたきがする。サーバサイドあたりの知識が弱いのでこれからもGo書きながらいろいろと勉強していきたい。今度はgoでDappsとか作ってみたいな。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1