<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 1、struct的序列化 struct中的變量命名必須以大寫字母開頭,否則在使用以下方法序列化時候,其值不會被序列化到[]byte之中,也就是說,反序列化后,其值會丟失。 ~~~ func?(b? *Block)?Serialize()?[]byte?{ varresult?bytes.Buffer?//定義一個buffer存儲序列化后的數據 //初始化一個encoder,gob是標準庫的一部分 //encoder根據參數的類型來創建,這里將編碼為字節數組 encoder?:=?gob.NewEncoder(&result) err?:=?encoder.Encode(b)?//編碼 if?err?!=?nil?{ ????????log.Panic(err)?//如果出錯,將記錄log后,Panic調用,立即終止當前函數的執行 ????} return?result.Bytes() } ~~~ # 2、VS-CODE的Debug配置 ![](https://img.kancloud.cn/4f/6e/4f6ee46317cd193ec9bc3c8ad06b212d_653x625.png) 如果程序是通過命令行參數運行的,配置文件參考如下: ~~~ { "version":?"0.2.0", "configurations":?[ ????????{ "name":?"Launch", "type":?"go", "request":?"launch", "mode":?"auto", "remotePath":?"", "port":?5546, "program":?"${fileDirname}", "env":?{}, "args":?["createblockchain","-address","Ivan"]//main的執行命令:main createblockchain -address Ivan //"args":?["printchain"]//main的執行命令:main printchain ????????} ????] } ~~~ # 3、flag包是解析命令行參數輸入的很好的工具 (1)定義CLI處理器 ~~~ typeCLIstruct{} ~~~ (2)檢測命令的合法性(普通檢查) ~~~ //validateArgs?校驗命令,如果無效,打印使用說明 //參數是否符合命令要求,不在這里進行檢查,而在執行命令前檢查 func?(cli?\*CLI)?validateArgs()?{ iflen(os.Args)?<?2?{?//所有命令至少有兩個參數,第一個是程序名稱,第二個是命名名稱 ????????cli.printUsage() ????????os.Exit(1) ????} } ~~~ (3)命令行使用說明 ~~~ //printUsage?打印命令行幫助信息 func?(cli?\*CLI)?printUsage()?{ ????fmt.Println("Usage:") ????fmt.Println("???getbalance?-address?ADDRESS??-?獲得某個地址的余額") ????fmt.Println("???createblockchain?-address?ADDRESS?-?創建一個新的區塊鏈并發送創始區塊獎勵給到address") ????fmt.Println("???printchain?-?打印區塊鏈中的所有區塊") ????fmt.Println("???send?-from?FROM?-to?To?-amount?-?發送amount數量的幣,從地址FROM到TO") } ~~~ (4)Run?讀取命令行參數,執行相應的命令 ~~~ //使用標準庫里面的?flag?包來解析命令行參數: func?(cli?*CLI)?Run()?{ ????cli.validateArgs() //定義名稱為"getbalance"的空的flagset集合 getBalanceCmd?:=?flag.NewFlagSet("getbalance",?flag.ExitOnError) //定義名稱為"createBlockchainCmd"的空的flagset集合 createBlockchainCmd?:=?flag.NewFlagSet("createblockchain",?flag.ExitOnError) //定義名稱為"sendCmd"的空的flagset集合 sendCmd?:=?flag.NewFlagSet("send",?flag.ExitOnError) //定義名稱為"printchain"的空的flagset集合 printChainCmd?:=?flag.NewFlagSet("printchain",?flag.ExitOnError) //String用指定的名稱給getBalanceAddress?新增一個字符串flag //以指針的形式返回getBalanceAddress getBalanceAddress?:=?getBalanceCmd.String("address",?"",?"獲得金錢的地址") createBlockchainAddress?:=?createBlockchainCmd.String("address",?"",?"接受挖出創始區塊獎勵的的地址") sendFrom?:=?sendCmd.String("from",?"",?"錢包源地址") sendTo?:=?sendCmd.String("to",?"",?"錢包目的地址") sendAmount?:=?sendCmd.Int("amount",?0,?"轉移資金的數量") //os.Args包含以程序名稱開始的命令行參數 switch?os.Args[1]?{?os.Args[0]為程序名稱,真正傳遞的參數index從1開始,一般而言Args\[1\]為命令名稱 case"getbalance": //Parse調用之前,必須保證getBalanceCmd所有的flag都已經定義在其中 err?:=?getBalanceCmd.Parse(os.Args\[2:\])?//僅解析參數,不含命令 if?err?!=?nil?{ ????????????log.Panic(err) ????????} case"createblockchain": err?:=?createBlockchainCmd.Parse(os.Args\[2:\]) if?err?!=?nil?{ ????????????log.Panic(err) ????????} case"printchain": //Parse調用之前,必須保證addBlockCmd所有的flag都已經定義在其中 //根據命令設計,這里將返回nil,所以在前面沒有定義接收解析后數據的flag //但printChainCmd的parsed=true err?:=?printChainCmd.Parse(os.Args\[2:\])?//僅僅解析參數,不含命令 if?err?!=?nil?{ ????????????log.Panic(err) ????????} case"send": err?:=?sendCmd.Parse(os.Args\[2:\]) if?err?!=?nil?{ ????????????log.Panic(err) ????????} default: ????????cli.printUsage() ????????os.Exit(1) ????} if?getBalanceCmd.Parsed()?{ if?*getBalanceAddress?==?""?{ ????????????getBalanceCmd.Usage() ????????????os.Exit(1) ????????} ????????cli.getBalance(\*getBalanceAddress) ????} if?createBlockchainCmd.Parsed()?{ if?*createBlockchainAddress?==?""?{ ????????????createBlockchainCmd.Usage() ????????????os.Exit(1) ????????} ????????cli.createBlockchain(\*createBlockchainAddress) ????} if?printChainCmd.Parsed()?{ ????????cli.printChain() ????} if?sendCmd.Parsed()?{ if?*sendFrom?==?""?||?*sendTo?==?""?||?*sendAmount?<=?0?{ ????????????sendCmd.Usage() ????????????os.Exit(1) ????????} ????????cli.send(\*sendFrom,?\*sendTo,?\*sendAmount) ????} } ~~~ ## 4、github與vs-code集成,同時打開多個github控制的項目 有時候,我們需要在一個vs-code界面上,同時打開多個受github控制的項目(每個項目為獨立的github倉庫),其做法如下: (1)在本地磁盤建立一個頂級文件夾; (2)打開VS-CODE,克隆存儲庫 ![](https://img.kancloud.cn/6a/6d/6a6d0914b006932cce14f482c2d501cb_901x547.png) 剛剛建立的本地頂級文件夾,輸入項目github地址。 (3)VS-CODE關閉文件夾,然后打開剛建立的頂級文件夾 這時候,所有的子文件夾會自動導入進來了。 頂級文件夾下的各子文件夾對應于子項目,獨立進行github更新。 平時工作,除非建立分支,一般操作三板斧:Add(+)、Commit、Push,將本地修改同步到云端。 ## 5、map類型的使用 map是go里面非常強大的類型,對于值為struct類型、數組或其他非常復雜的結構的key-value列表,非常適合使用它來進行存儲處理。 ## 6、append的兩種用法 ~~~ x := []int {1,2,3} y := []int {4,5,6} //注意下面這兩個區別 fmt.Println(append(x,4,5,6)) fmt.Println(append(x,y...)); ~~~ 第一種用法中,第一個參數為slice,后面可以添加多個參數,這種情況一般是將一個或多個元素加入到現有的數組之中: x=append(x,4,5,6) 第二種用法,是將兩個slice拼接在一起,在第二個slice的名稱后面加三個點,構建一個新的數組,這時候append只支持兩個參數,不支持任意個數的參數。 z:=append(x,y...) ## 7、數組的切片引用方式:復用 我們一般在構建了數組實例后,通過函數或方法返回給調用者使用,一般不會直接返回數組指針,而是以切片形式,返回給調用者。這種方式是Go里面的普遍方式。函數或方法內部也是這么使用。 ~~~ func checksum(payload []byte) []byte { firstSHA := sha256.Sum256(payload) secondSHA := sha256.Sum256(firstSHA[:])//引用firstSHA 數組的全部切片 return secondSHA[:addressChecksumLen]//返回用secondSHA的部分切片 } ~~~ ## 8、判斷文件是否存在 ~~~ if_,?err?:=?os.Stat(walletFile);?os.IsNotExist(err)?{ return?err ??} ~~~ ## 9、[]byte轉為字符串: hex.EncodeToString(prevTX.ID)//prevTX.ID為[]byte類型 ## 10、break語句 (1)break//直接退出當前層次的循環 (2)break WORK//退出WORK標簽對應的代碼塊,標簽要求必須定義在對應的 for、switch 和 select 的代碼塊上 ## 11、vs-code多命令窗口運行 vs-code可以多窗口運行。 ![](https://img.kancloud.cn/59/27/59279a49d1aeae04d667c05b016fab17_2091x916.png) 每一個窗口都可以獨立設置環境變量 如第一個窗口設置:set NODE_ID=3000,第二個窗口設置環境變量:set NODE_ID=3001,第三個窗口設置為set NODE_ID=3002。 在命令行窗口運行服務后,如希望暫停,通過鍵盤上ctrl+c組合鍵執行。 ## 12、go env 可以使用命令行查看 Go 開發包的環境變量配置信息,這些配置信息里可以查看到當前的 GOPATH 路徑設置情況。在命令行中運行`go env`。 ## 13、gobEncode go內置的gobEncode,可以將一個stuct轉換成一個[]byte數組,一個典型的用途是傳輸遠程過程調用(RPC)的參數和結果: ~~~ data?:=?block{nodeAddress,?b.Serialize()} payload?:=?gobEncode(data) ~~~ ~~~ func gobEncode(data?interface{})?[]byte?{ varbuff?bytes.Buffer enc?:=?gob.NewEncoder(&buff) err?:=?enc.Encode(data) if?err?!=?nil?{ ????????log.Panic(err) ????} return?buff.Bytes() } ~~~ 與此對應的是## GobDecoder。 ## 14、通道chan chan 可以理解為隊列,遵循先進先出的規則,用于在不同goroutine之間通信。 ``` // 聲明不帶緩沖的通道 ch1 := make(chan string) // 聲明帶10個緩沖的通道 ch2 := make(chan string, 10) // 聲明只讀通道 ch3 := make(<-chan string) // 聲明只寫通道 ch4 := make(chan<- string) ``` 注意: 不帶緩沖的通道,進和出都會阻塞。 帶緩沖的通道,進一次長度 +1,出一次長度 -1,如果長度等于緩沖長度時,再進就會阻塞。 ### 寫入 chan ``` ch1 := make(chan string, 10) ch1 <- "a" ``` ### 讀取 chan ``` val, ok := <- ch1 // 或 val := <- ch1 ``` ### 關閉 chan ``` close(chan) ``` 注意: * close 以后不能再寫入,寫入會出現 panic * 重復 close 會出現 panic * 只讀的 chan 不能 close * close 以后還可以讀取數據
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看