<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Golang on Quietbo</title><link>https://quietbo.com/categories/golang/</link><description>Recent content in Golang on Quietbo</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sun, 17 Nov 2024 15:27:57 +0000</lastBuildDate><atom:link href="https://quietbo.com/categories/golang/index.xml" rel="self" type="application/rss+xml"/><item><title>[Golang] goroutine &amp; sync.WaitGroup</title><link>https://quietbo.com/2024/11/17/golang-goroutine-sync-waitgroup/</link><pubDate>Sun, 17 Nov 2024 15:27:57 +0000</pubDate><guid>https://quietbo.com/2024/11/17/golang-goroutine-sync-waitgroup/</guid><description>&lt;p&gt;Goroutine 是 Go 語言中一種輕量級的並發執行單元。我們可以使用 Goroutine 來實現並發編程,提高程式的效率和性能。&lt;/p&gt;
&lt;p&gt;sync.WaitGroup 是 Go 標準庫中提供的一個同步原語,它用於等待一組 Goroutine 全部執行完畢。我們可以通過以下方式使用 sync.WaitGroup:&lt;/p&gt;
&lt;p&gt;創建 WaitGroup 實例:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wg := new(sync.WaitGroup)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用 wg.Add(n) 可以將 WaitGroup 的計數器增加 n。每啟動一個新的 Goroutine,都需要增加計數器。 增加 WaitGroup 計數器:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wg.Add(n)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;等待所有 Goroutine 完成&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wg.Wait()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 main 函數中,使用 wg.Wait() 可以阻塞直到所有 Goroutine 都完成。&lt;/p&gt;
&lt;p&gt;在 Goroutine 中減少計數器:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;defer wg.Done()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 Goroutine 內部,使用 defer wg.Done() 可以在 Goroutine 退出時,將 WaitGroup 的計數器減 1。&lt;/p&gt;
&lt;p&gt;下方為實作的code，找質數：一般如果用for迴圈會非常慢&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;package main

import (
 &amp;#34;fmt&amp;#34;
 &amp;#34;time&amp;#34;
)

func main() {
 num := 300000
 start := time.Now()
 for i := 1; i &amp;lt;= num; i++ {
 if isPrime(i) {
 fmt.Println(i)
 }
 }
 end := time.Now()
 fmt.Println(end.Unix() - start.Unix(), &amp;#34;seconds&amp;#34;)
}

func isPrime(num int) bool {
 if num == 1 {
 return false
 } else if num == 2 {
 return true
 } else {
 for i := 2; i &amp;lt; num; i++ {
 if num % i == 0 {
 return false
 }
 }
 return true
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;單純只使用Goroutine，在使用findPrimes之前加go，會沒辦法知道實際到底花幾秒的時間，以及main時間到就會結束。 main 啟動了 300000 個 Goroutine，每個 Goroutine 調用 findPrimes 函數。 但是 main 函數並沒有等待所有 Goroutine 執行完畢,而是直接等待了 2 秒鐘輸出 done。 單純使用 Goroutine 而不使用 sync.WaitGroup 或其他同步機制,無法確保所有任務都已完成,也無法準確測量總的執行時間。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;package main

import (
 &amp;#34;fmt&amp;#34;
 &amp;#34;time&amp;#34;
)

func main() {
 num := 300000
 for i := 1; i &amp;lt;= num; i++ {
 go findPrimes(i)
 }
 time.Sleep(2 * time.Second)
 fmt.Println(&amp;#34;done&amp;#34;)
}

func findPrimes(num int) {
 if num == 1 {
 return
 } else if num == 2 {
 fmt.Println(num)
 } else {
 for i := 2; i &amp;lt; num; i++ {
 if num % i == 0 {
 return
 }
 }
 fmt.Println(num)
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;因此,我們無法確定在 “done” 輸出之前,所有 findPrimes 函數都已經執行完畢，要解決這個問題,最簡單的方法就是使用 sync.WaitGroup。&lt;/p&gt;
&lt;p&gt;下方正確使用了 sync.WaitGroup 來確保所有 Goroutine 都執行完畢,並且能夠正確地計算整個過程的耗時。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;package main

import (
 &amp;#34;fmt&amp;#34;
 &amp;#34;sync&amp;#34;
 &amp;#34;time&amp;#34;
)

func main() {
 wg := new(sync.WaitGroup)
 num := 300000
 wg.Add(num) // 設置需要檢查的數字範圍為 1 到 300000
 start := time.Now().Unix()
 for i := 1; i &amp;lt;= num; i++ {
 go findPrimes(i, wg) // 啟動 num 個 goroutine,每個 goroutine 都調用 findPrimes 函數。

 }
 wg.Wait() // 在所有goroutine完成之前, main 函數會一直等待,使用 wg.Wait()
 end := time.Now().Unix()
 fmt.Print(end-start, &amp;#34;seconds&amp;#34;)
}

func findPrimes(num int, wg *sync.WaitGroup) {
 defer wg.Done() // 確保在函數退出時,WaitGroup 的計數器會被減 1
 if num == 1 {
 return
 } else if num == 2 {
 fmt.Println(num)
 } else {
 for i := 2; i &amp;lt; num; i++ {
 if num%i == 0 {
 return
 }
 }
 fmt.Println(num)
 }
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] aes各种加密方式（CBC/ECB/CFB）含Code</title><link>https://quietbo.com/2022/12/27/golang-aes%E5%90%84%E7%A7%8D%E5%8A%A0%E5%AF%86%E6%96%B9%E5%BC%8F%EF%BC%88cbc-ecb-cfb%EF%BC%89%E5%90%ABcode/</link><pubDate>Tue, 27 Dec 2022 10:12:09 +0000</pubDate><guid>https://quietbo.com/2022/12/27/golang-aes%E5%90%84%E7%A7%8D%E5%8A%A0%E5%AF%86%E6%96%B9%E5%BC%8F%EF%BC%88cbc-ecb-cfb%EF%BC%89%E5%90%ABcode/</guid><description>&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 Code
 &lt;/li&gt;
 &lt;li&gt;
 輸出結果
 &lt;/li&gt;
 &lt;li&gt;
 線上驗證(網站)
 &lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "bytes"
 "crypto/aes"
 "crypto/cipher"
 "crypto/rand"
 "encoding/base64"
 "encoding/hex"
 "io"
 "log"
)

func main() {
 origData := []byte("Hello World") // 待加密數據(明文)
 key := []byte("ABCDEFGHIJKLMNOP") // 密鑰，長度必為16
 log.Println("原文：", string(origData))

 log.Println("------------------ CBC模式 --------------------")
 encrypted := AesEncryptCBC(origData, key)
 log.Println("密文(hex)：", hex.EncodeToString(encrypted))
 log.Println("密文(base64)：", base64.StdEncoding.EncodeToString(encrypted))
 decrypted := AesDecryptCBC(encrypted, key)
 log.Println("解密结果：", string(decrypted))

 log.Println("------------------ ECB模式 --------------------")
 encrypted = AesEncryptECB(origData, key)
 log.Println("密文(hex)：", hex.EncodeToString(encrypted))
 log.Println("密文(base64)：", base64.StdEncoding.EncodeToString(encrypted))
 decrypted = AesDecryptECB(encrypted, key)
 log.Println("解密结果：", string(decrypted))

 log.Println("------------------ CFB模式 --------------------")
 encrypted = AesEncryptCFB(origData, key)
 log.Println("密文(hex)：", hex.EncodeToString(encrypted))
 log.Println("密文(base64)：", base64.StdEncoding.EncodeToString(encrypted))
 decrypted = AesDecryptCFB(encrypted, key)
 log.Println("解密结果：", string(decrypted))
}

// =================== CBC ======================
func AesEncryptCBC(origData []byte, key []byte) (encrypted []byte) {
 // 分组秘钥
 // NewCipher该函数限制了输入k的长度必须为16, 24或者32
 block, _ := aes.NewCipher(key)
 blockSize := block.BlockSize() // 获取秘钥块的长度
 origData = pkcs5Padding(origData, blockSize) // 补全码
 blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) // 加密模式
 encrypted = make([]byte, len(origData)) // 创建数组
 blockMode.CryptBlocks(encrypted, origData) // 加密
 return encrypted
}
func AesDecryptCBC(encrypted []byte, key []byte) (decrypted []byte) {
 block, _ := aes.NewCipher(key) // 分组秘钥
 blockSize := block.BlockSize() // 获取秘钥块的长度
 blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) // 加密模式
 decrypted = make([]byte, len(encrypted)) // 创建数组
 blockMode.CryptBlocks(decrypted, encrypted) // 解密
 decrypted = pkcs5UnPadding(decrypted) // 去除补全码
 return decrypted
}
func pkcs5Padding(ciphertext []byte, blockSize int) []byte {
 padding := blockSize - len(ciphertext)%blockSize
 padtext := bytes.Repeat([]byte{byte(padding)}, padding)
 return append(ciphertext, padtext...)
}
func pkcs5UnPadding(origData []byte) []byte {
 length := len(origData)
 unpadding := int(origData[length-1])
 return origData[:(length - unpadding)]
}

// =================== ECB ======================
func AesEncryptECB(origData []byte, key []byte) (encrypted []byte) {
 cipher, _ := aes.NewCipher(generateKey(key))
 length := (len(origData) + aes.BlockSize) / aes.BlockSize
 plain := make([]byte, length*aes.BlockSize)
 copy(plain, origData)
 pad := byte(len(plain) - len(origData))
 for i := len(origData); i &amp;lt; len(plain); i++ {
 plain[i] = pad
 }
 encrypted = make([]byte, len(plain))
 // 分组分块加密
 for bs, be := 0, cipher.BlockSize(); bs &amp;lt;= len(origData); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
 cipher.Encrypt(encrypted[bs:be], plain[bs:be])
 }

 return encrypted
}
func AesDecryptECB(encrypted []byte, key []byte) (decrypted []byte) {
 cipher, _ := aes.NewCipher(generateKey(key))
 decrypted = make([]byte, len(encrypted))
 //
 for bs, be := 0, cipher.BlockSize(); bs &amp;lt; len(encrypted); bs, be = bs+cipher.BlockSize(), be+cipher.BlockSize() {
 cipher.Decrypt(decrypted[bs:be], encrypted[bs:be])
 }

 trim := 0
 if len(decrypted) &amp;gt; 0 {
 trim = len(decrypted) - int(decrypted[len(decrypted)-1])
 }

 return decrypted[:trim]
}
func generateKey(key []byte) (genKey []byte) {
 genKey = make([]byte, 16)
 copy(genKey, key)
 for i := 16; i &amp;lt; len(key); {
 for j := 0; j &amp;lt; 16 &amp;&amp; i &amp;lt; len(key); j, i = j+1, i+1 {
 genKey[j] ^= key[i]
 }
 }
 return genKey
}

// =================== CFB ======================
func AesEncryptCFB(origData []byte, key []byte) (encrypted []byte) {
 block, err := aes.NewCipher(key)
 if err != nil {
 panic(err)
 }
 encrypted = make([]byte, aes.BlockSize+len(origData))
 iv := encrypted[:aes.BlockSize]
 if _, err := io.ReadFull(rand.Reader, iv); err != nil {
 panic(err)
 }
 stream := cipher.NewCFBEncrypter(block, iv)
 stream.XORKeyStream(encrypted[aes.BlockSize:], origData)
 return encrypted
}
func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte) {
 block, _ := aes.NewCipher(key)
 if len(encrypted) &amp;lt; aes.BlockSize {
 panic("ciphertext too short")
 }
 iv := encrypted[:aes.BlockSize]
 encrypted = encrypted[aes.BlockSize:]

 stream := cipher.NewCFBDecrypter(block, iv)
 stream.XORKeyStream(encrypted, encrypted)
 return encrypted
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;執行結果&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;2022/12/27 18:03:51 原文： {"http_method": "POST", "http_service": "openapi", "http_uri": "/app/openapi/loginweb", "uri_params": {}, "body": {"app_id": "bens", "app_userid": "101a"}}
2022/12/27 18:03:51 ------------------ CBC模式 --------------------
2022/12/27 18:03:51 密文(hex)： 15cc9814d9c06fd3816ba2a4f842f6124a9dfd653c6ceb427377484541e680fe7c040613389f2233f0c505968d4c791cd29ef6c2c189e4f8b60543459bf31c2bebb3b3cb2e6341ffa0d0c44f3c29e04f7f5bd367472a5a1d9c78014b44e2584cf058f2abbc31913d46acc451d3459e13e021b4cf9df0bb5eb5d9982cca8a4897f99f18b9e3c4c355584888ebd1270a3368e908b2c15c1ba4095aa07d6cd59038
2022/12/27 18:03:51 密文(base64)： FcyYFNnAb9OBa6Kk+EL2Ekqd/WU8bOtCc3dIRUHmgP58BAYTOJ8iM/DFBZaNTHkc0p72wsGJ5Pi2BUNFm/McK+uzs8suY0H/oNDETzwp4E9/W9NnRypaHZx4AUtE4lhM8Fjyq7wxkT1GrMRR00WeE+AhtM+d8LtetdmYLMqKSJf5nxi548TDVVhIiOvRJwozaOkIssFcG6QJWqB9bNWQOA==
2022/12/27 18:03:51 解密结果： {"http_method": "POST", "http_service": "openapi", "http_uri": "/app/openapi/loginweb", "uri_params": {}, "body": {"app_id": "bens", "app_userid": "101a"}}
2022/12/27 18:03:51 ------------------ ECB模式 --------------------
2022/12/27 18:03:51 密文(hex)： 860ca9b68b3684b287af3375bad0c97377acef832b6693c2d97c74c2c563f2c498b645673d4724d3c5a41e3fde6741b5d176c17b1c94b36283b7f9c6f860c487ea7b03124c2418bb73607fe684bf93c2f6890d0e195b3316140f6595c02403b47b15f4c0a58ad794ad6f98a626a0e0df4bc3fc72249ed196c663a9b06545ba71d25ee921fbf01f8e924e110f6aabea60d256a104e57174ff3fd725a6aeb57638
2022/12/27 18:03:51 密文(base64)： hgyptos2hLKHrzN1utDJc3es74MrZpPC2Xx0wsVj8sSYtkVnPUck08WkHj/eZ0G10XbBexyUs2KDt/nG+GDEh+p7AxJMJBi7c2B/5oS/k8L2iQ0OGVszFhQPZZXAJAO0exX0wKWK15Stb5imJqDg30vD/HIkntGWxmOpsGVFunHSXukh+/AfjpJOEQ9qq+pg0lahBOVxdP8/1yWmrrV2OA==
2022/12/27 18:03:51 解密结果： {"http_method": "POST", "http_service": "openapi", "http_uri": "/app/openapi/loginweb", "uri_params": {}, "body": {"app_id": "bens", "app_userid": "101a"}}
2022/12/27 18:03:51 ------------------ CFB模式 --------------------
2022/12/27 18:03:51 密文(hex)： b326c923ef88752f4f604b41722fd1b3a0dced22a81b206237ff3055d5ebebca0456b6bdcaae9816e29247822ec42dbdaea560fe5d5643f40f0f4a55d5528f97c5bd59e55b0881345bf60f17a2da37c0d7d63dea5da337491314155480c045d448cf66089a506ade54b0e0ac34fc0136de3230432c1a8e159a1b150802147f225d9f8aebb7b67e45959c2b018240f5d121b7d619686630e152d83ab20a7847cf81811bc0183d574acb496a
2022/12/27 18:03:51 密文(base64)： sybJI++IdS9PYEtBci/Rs6Dc7SKoGyBiN/8wVdXr68oEVra9yq6YFuKSR4IuxC29rqVg/l1WQ/QPD0pV1VKPl8W9WeVbCIE0W/YPF6LaN8DX1j3qXaM3SRMUFVSAwEXUSM9mCJpQat5UsOCsNPwBNt4yMEMsGo4VmhsVCAIUfyJdn4rrt7Z+RZWcKwGCQPXRIbfWGWhmMOFS2DqyCnhHz4GBG8AYPVdKy0lq
2022/12/27 18:03:51 解密结果： {"http_method": "POST", "http_service": "openapi", "http_uri": "/app/openapi/loginweb", "uri_params": {}, "body": {"app_id": "bens", "app_userid": "101a"}}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;驗證網站:&lt;br&gt;
&lt;a class="link" href="https://totools.site/AES" target="_blank" rel="noopener"
 &gt;AES在線加密解密工具&lt;/a&gt;&lt;/p&gt;</description></item><item><title>[Golang] Gin &amp; Goland &amp; go.mod 快速建立</title><link>https://quietbo.com/2022/10/26/golang-gin-goland-go-mod-%E5%BF%AB%E9%80%9F%E5%BB%BA%E7%AB%8B/</link><pubDate>Tue, 25 Oct 2022 17:49:24 +0000</pubDate><guid>https://quietbo.com/2022/10/26/golang-gin-goland-go-mod-%E5%BF%AB%E9%80%9F%E5%BB%BA%E7%AB%8B/</guid><description>&lt;p&gt;打開Goland後main.go檔內複製下方的Code:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "github.com/gin-gonic/gin"
)
func main() {
 app := gin.Default()
 app.GET("/hello/:name", func(c *gin.Context) {
 name := c.Param("name")
 c.JSON(200, gin.H{
 "message": "hello " + name,
 })
 })
 err := app.Run(":8080")
 if err != nil {
 panic(err)
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;會看到很多紅字如下圖&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/CaqIcVr.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;打開Goland的file -&amp;gt; settings -&amp;gt; Go Modules -&amp;gt;&lt;br&gt;
將Enable Go modules integration打勾&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/CCEOu0Z.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;再Goland下方打開terminal，輸入&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;$ go mod init [project_name]
$ go mod tidy&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/pn7NIKz.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;此時的go.mod會自動下載&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;module do_gowork

go 1.19

require github.com/gin-gonic/gin v1.8.1

require (
 github.com/gin-contrib/sse v0.1.0 // indirect
 github.com/go-playground/locales v0.14.0 // indirect
 github.com/go-playground/universal-translator v0.18.0 // indirect
 github.com/go-playground/validator/v10 v10.10.0 // indirect
 github.com/goccy/go-json v0.9.7 // indirect
 github.com/json-iterator/go v1.1.12 // indirect
 github.com/leodido/go-urn v1.2.1 // indirect
 github.com/mattn/go-isatty v0.0.14 // indirect
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
 github.com/modern-go/reflect2 v1.0.2 // indirect
 github.com/pelletier/go-toml/v2 v2.0.1 // indirect
 github.com/ugorji/go/codec v1.2.7 // indirect
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
 golang.org/x/text v0.3.6 // indirect
 google.golang.org/protobuf v1.28.0 // indirect
 gopkg.in/yaml.v2 v2.4.0 // indirect
)&lt;/code&gt;&lt;/pre&gt;&lt;figure class="wp-block-image"&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/AE6i33f.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;注意，go mod tidy有移除「沒使用的依賴這功能」，實際上是需要使用來取得library。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;go get [library]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;空白處點選右鍵，Run ‘go build main.go’&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/fw3ni1J.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;執行成功可看到下面這些訊息&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env: export GIN_MODE=release
 - using code: gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET /hello/:name --&amp;gt; main.main.func1 (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :8080&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打開瀏覽器輸入:&lt;br&gt;
http://127.0.0.1:8080/hello/world&lt;/p&gt;
&lt;p&gt;{“message”:”hello world”}&lt;/p&gt;</description></item><item><title>[Golang] 創建BOT&amp;發送訊息</title><link>https://quietbo.com/2022/09/19/golang-%E5%89%B5%E5%BB%BAbot%E7%99%BC%E9%80%81%E8%A8%8A%E6%81%AF/</link><pubDate>Mon, 19 Sep 2022 10:00:42 +0000</pubDate><guid>https://quietbo.com/2022/09/19/golang-%E5%89%B5%E5%BB%BAbot%E7%99%BC%E9%80%81%E8%A8%8A%E6%81%AF/</guid><description>&lt;h2 id="創建bot加入好友並取得token"&gt;創建BOT，加入好友並取得token
&lt;/h2&gt;&lt;p&gt;打開Telegram搜尋:&lt;br&gt;
@BotFather&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/cZZDRgu.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;加入好友後，輸入/start 會提供些指令讓你選擇。&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 /start :用戶開始和機器人進行交互
 &lt;/li&gt;
 &lt;li&gt;
 /help :返回幫助信息
 &lt;/li&gt;
 &lt;li&gt;
 /setting :返回機器人的設置界面用戶在首次向機器人發信息之前會看到/start按鈕，在菜單中（機器人信息頁）可以看到幫助和設置鏈接。
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;創建BOT過程如下, 成功會返回一段訊息:&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/2NosBTo.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;藍框: 用來加該機器人好友的，建議直接點擊加入，先成為好友。&lt;br&gt;
紅框: 該bot的token，主要用來操控BOT，要記住!!&lt;/p&gt;
&lt;h2 id="取得chat-id"&gt;取得chat id
&lt;/h2&gt;&lt;p&gt;需要chat id，bot才知道要傳送訊息給哪個使用者或群組。&lt;/p&gt;
&lt;p&gt;首先，加入Bot好友後，傳一個訊息給這支BOT，例如”testbot”，發送成功後打開瀏覽器輸入&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;https://api.telegram.org/bot{token}/getUpdates&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;範例:&lt;br&gt;
&lt;a class="link" href="https://api.telegram.org/bot5630000628:AAH2XXXXXXXXXXXXXXXXXXXXXXXXXXXXn2zo/getUpdates" target="_blank" rel="noopener"
 &gt;https://api.telegram.org/bot5630000628:AAH2XXXXXXXXXXXXXXXXXXXXXXXXXXXXn2zo/getUpdates&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;會看到json資料，從裡面我們可以得到chat_id，建議先利用這網站把Json轉成可讀性高一點&lt;br&gt;
&lt;a class="link" href="https://tw.piliapp.com/json/formatter" target="_blank" rel="noopener"
 &gt;JSON格式化&lt;/a&gt;&lt;br&gt;
轉成功後再貼在記事本，搜尋剛剛傳給bot的訊息:testbot&lt;br&gt;
會看到有一段，像下圖的訊息&lt;figure class="wp-block-image"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img decoding="async" src="https://i.imgur.com/NwJIyNx.png" alt="" /&gt; &lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;取得那段數字就好。&lt;/p&gt;
&lt;h2 id="使用程式發送訊息"&gt;使用程式發送訊息
&lt;/h2&gt;&lt;p&gt;把chat id和token帶入下方的const內。&lt;/p&gt;
&lt;p&gt;並開啟終端機輸入:go get -u github.com/go-telegram-bot-api/telegram-bot-api&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
 tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
 "log"
)
var bot *tgbotapi.BotAPI

const (
 chatID = 1234567 //要傳送訊息給指定用戶
 youToken = "5630000628:AAH2XXXXXXXXXXXXXXXXXXXXXXXXXXXXn2zo"
)

func main() {
 var err error
 bot, err = tgbotapi.NewBotAPI(youToken)
 if err != nil {
 log.Fatal(err)
 }
 bot.Debug = false

 link := fmt.Sprintf(`&amp;lt;a href="%s"&amp;gt;[google]&amp;lt;/a&amp;gt;`, "https://www.google.com.tw/")
 sendMsg(link)
}

func sendMsg(msg string) {
 NewMsg := tgbotapi.NewMessage(chatID, msg)
 NewMsg.ParseMode = tgbotapi.ModeHTML //傳送html格式的訊息
 _, err := bot.Send(NewMsg)
 if err == nil {
 log.Printf("Send telegram message success")
 } else {
 log.Printf("Send telegram message error")
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用程式運行發送後就會收到 google 連結的的訊息了&lt;br&gt;
&lt;img decoding="async" src="https://i.imgur.com/auvOu34.png" alt="" /&gt;&lt;/p&gt;</description></item><item><title/><link>https://quietbo.com/2022/09/12/golang-goroutine-channel/</link><pubDate>Mon, 12 Sep 2022 14:41:24 +0000</pubDate><guid>https://quietbo.com/2022/09/12/golang-goroutine-channel/</guid><description>&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-1'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2022/09/12/golang-goroutine-channel/#Golang_goroutine_channel" &gt;[Golang] goroutine &amp; channel&lt;/a&gt;&lt;ul class='ez-toc-list-level-2' &gt;
 &lt;li class='ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2022/09/12/golang-goroutine-channel/#Channel" &gt;Channel&lt;/a&gt;&lt;ul class='ez-toc-list-level-3' &gt;
 &lt;li class='ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-3" href="https://quietbo.com/2022/09/12/golang-goroutine-channel/#%E9%A1%9E%E5%9E%8B%E8%88%87%E5%89%B5%E5%BB%BA" &gt;類型與創建&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-4" href="https://quietbo.com/2022/09/12/golang-goroutine-channel/#%E7%99%BC%E9%80%81%E8%88%87%E6%8E%A5%E6%94%B6" &gt;發送與接收&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
&lt;pre&gt;&lt;code&gt; &amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-5&amp;quot; href=&amp;quot;https://quietbo.com/2022/09/12/golang-goroutine-channel/#select&amp;quot; &amp;gt;select&amp;lt;/a&amp;gt;&amp;lt;ul class='ez-toc-list-level-3' &amp;gt;
 &amp;lt;li class='ez-toc-heading-level-3'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-6&amp;quot; href=&amp;quot;https://quietbo.com/2022/09/12/golang-goroutine-channel/#%E5%9F%BA%E6%9C%AC%E8%AA%9E%E6%B3%95&amp;quot; &amp;gt;基本語法&amp;lt;/a&amp;gt;
 &amp;lt;/li&amp;gt;
 &amp;lt;/ul&amp;gt;
 &amp;lt;/li&amp;gt;
 &amp;lt;/ul&amp;gt;
&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h1 id="golang-goroutine--channel"&gt;&lt;span class="ez-toc-section" id="Golang_goroutine_channel"&gt;&lt;/span&gt;[Golang] goroutine &amp;amp; channel&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h1&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 Go &lt;a href="https://www.runoob.com/go/go-concurrent.html"&gt;併發&amp;通道（channel）&lt;/a&gt;
 &lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="channel"&gt;&lt;span class="ez-toc-section" id="Channel"&gt;&lt;/span&gt;Channel&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;Channel 是 Go 語言中用於 goroutine 之間通信的管道，是 Go 並發編程模型的核心組件之一。&lt;br&gt;
基本概念&lt;br&gt;
Channel 提供了一種 goroutine 之間的通信機制，使一個 goroutine 可以向另一個 goroutine 發送數據，而無需顯式的鎖或條件變量。&lt;/p&gt;
&lt;h3 id="類型與創建"&gt;&lt;span class="ez-toc-section" id="%E9%A1%9E%E5%9E%8B%E8%88%87%E5%89%B5%E5%BB%BA"&gt;&lt;/span&gt;類型與創建&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;// 創建不同類型的 channel
ch1 := make(chan int) // 無緩衝的整數 channel
ch2 := make(chan string, 10) // 有 10 個緩衝區的字符串 channel
ch3 := make(chan interface{}) // 任意類型的 channel&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="發送與接收"&gt;&lt;span class="ez-toc-section" id="%E7%99%BC%E9%80%81%E8%88%87%E6%8E%A5%E6%94%B6"&gt;&lt;/span&gt;發送與接收&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;// 發送數據
ch &amp;lt;- value

// 接收數據
value := &amp;lt;-ch
value, ok := &amp;lt;-ch // ok 表示 channel 是否已關閉&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;goroutine + Channel 範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;package main
import "fmt"
import "time"
func main() {
 ch1 := make(chan int, 1)
 ch2 := make(chan string, 1)
 ch3 := make(chan interface{}, 1)

 ch1 &amp;lt;- 1 // ch1 緩衝區已滿

 // 創建 goroutine 來接收第一個值
 go func() {
 time.Sleep(2 * time.Second) // 等待1秒
 fmt.Println(&amp;lt;-ch1) // 1，此時釋放 ch1 的空間
 }()

 ch1 &amp;lt;- 3 // 這裡會阻塞，直到上面的 goroutine 從 ch1 接收數據
 // 由於上面的 goroutine 有2秒延遲，這里會等待約2秒

 ch2 &amp;lt;- "name"
 ch3 &amp;lt;- "hi"

 fmt.Println(&amp;lt;-ch1) // 3
 fmt.Println(&amp;lt;-ch2) // "name"
 fmt.Println(&amp;lt;-ch3) // "hi"
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顯示如下:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;1
3
name
hi&lt;/code&gt;&lt;/pre&gt;
&lt;ol start="2" class="wp-block-list"&gt;
 &lt;li&gt;
 範例&amp;說明
 &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;package main
import "fmt"

func main() {
 // 創建通道
 c := make(chan int)

 //併發執行
 go ifunc(c)
 for i := 1; i &amp;lt;= 10; i++{
 // 將數據i發送給通道
 c &amp;lt;- i
 }

 // 通道ifunc結束讀取數據
 c&amp;lt;- 100

 //等於ifunc結束
 fmt.Println(&amp;lt;-c)
}

func ifunc(c chan int) {

 // 阻塞等待數據
 for {
 //從通道獲取一個數據
 data := &amp;lt;- c

 // 當取得的數據為100則結束阻塞
 if data == 100{
 break
 }
 // 輸出數據
 fmt.Println(data)
 }
 // 通知main結束
 c&amp;lt;-0
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;output:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;1
2
3
4
5
6
7
8
9
10
0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;補充:&lt;br&gt;
可以在&lt;br&gt;
fmt.Println(&amp;lt;-c)與fmt.Println(data)之前，print隨便一個數值，&lt;br&gt;
就可以看到，輸出模式取決於 Go 調度器如何在這兩個 goroutine 之間切換&lt;/p&gt;
&lt;h2 id="select"&gt;&lt;span class="ez-toc-section" id="select"&gt;&lt;/span&gt;select&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;select 是 Go 語言中的一個控制結構，專門用於處理多個通道操作。它的主要用途是同時等待多個通道的操作（發送或接收），並在其中一個操作可以進行時執行對應的代碼。&lt;/p&gt;
&lt;h3 id="基本語法"&gt;&lt;span class="ez-toc-section" id="%E5%9F%BA%E6%9C%AC%E8%AA%9E%E6%B3%95"&gt;&lt;/span&gt;基本語法&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;select {
case &amp;lt;-chan1:
 // 從 chan1 接收到數據時執行
case chan2 &amp;lt;- value:
 // 向 chan2 發送數據成功時執行
case x := &amp;lt;-chan3:
 // 從 chan3 接收到數據並賦值給 x 時執行
default:
 // 沒有通道操作就緒時執行（非阻塞模式）
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a class="link" href="https://www.runoob.com/go/go-select-statement.html" target="_blank" rel="noopener"
 &gt;select&lt;/a&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;package main

import (
 "fmt"
 "time"
)

func main() {
 // 創建兩個通道
 ch1 := make(chan string)
 ch2 := make(chan string)

 // 在一個 goroutine 中，1秒後發送數據到 ch1
 go func() {
 time.Sleep(1 * time.Second)
 ch1 &amp;lt;- "來自通道1的數據"
 }()
 go func() {
 time.Sleep(1 * time.Second)
 ch1 &amp;lt;- "來自通道1-1的數據"
 }()
 // 在另一個 goroutine 中，2秒後發送數據到 ch2
 go func() {
 time.Sleep(2 * time.Second)
 ch2 &amp;lt;- "來自通道2的數據"
 }()

 go func() {
 time.Sleep(2 * time.Second)
 ch2 &amp;lt;- "來自通道2-1的數據"
 }()

 // 使用 select 監聽兩個通道
 for i := 0; i &amp;lt; 4; i++ {
 select {
 case msg1 := &amp;lt;-ch1:
 fmt.Println("接收到:", msg1)
 case msg2 := &amp;lt;-ch2:
 fmt.Println("接收到:", msg2)
 case &amp;lt;-time.After(3 * time.Second):
 fmt.Println("操作超時")
 }
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;output:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;接收到: 來自通道1-1的數據
接收到: 來自通道1的數據
接收到: 來自通道2的數據
接收到: 來自通道2-1的數據&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] 接口interface</title><link>https://quietbo.com/2022/09/10/golang-%E6%8E%A5%E5%8F%A3interface/</link><pubDate>Sat, 10 Sep 2022 15:10:52 +0000</pubDate><guid>https://quietbo.com/2022/09/10/golang-%E6%8E%A5%E5%8F%A3interface/</guid><description>&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;type 類型名 struct{
 字段1 類型
 字段2 類型
}

定義接口
type interface_name interface{
 方法名 method_name1
 方法名 method_name2
 ....
}

定義結構體
type struct_name struct{

}


func(struct_name_var struct_name) method_name1() [返回類型]{
 //方法實現
}


func(struct_name_var struct_name) method_nam2() [返回類型]{
 //方法實現
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"


type Mobile interface {
 call()
 message()
}

type Iphone struct {
}

type Samsung struct{
}

func (iphone13 Iphone) call(){
 fmt.Println("iphone13, call phone number")
}

func (iphone13 Iphone) message(){
 fmt.Println("iphone13, use message")
}

func (s22 Samsung) call(){
 fmt.Println("samsung, call phone number")
}

func (s22 Samsung) message(){
 fmt.Println("samsung, use message")
}

func main() {
 var mobile Mobile
 mobile=new(Iphone)
 mobile.call()
 mobile.message()


 var mobile2 Mobile
 mobile2=new(Samsung)
 mobile2.call()
 mobile2.message()
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顯示&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=" line-numbers"&gt;iphone13, call phone number
iphone13, use message
samsung, call phone number
samsung, use message&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="空接口類型"&gt;空接口類型
&lt;/h2&gt;&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
)

func main() {
 var any interface{}
 any = 100
 fmt.Printf("value:%d type:%T \n", any, any)

 any = "aaa"
 fmt.Printf("value:%s type:%T \n", any, any)

 testFunc(100)
 testFunc("test")
}

func testFunc(par interface{}){
 fmt.Println(par)
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=" line-numbers"&gt;value:100 type:int 
value:aaa type:string 
100
test&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] 結構體struct &amp;方法接收器</title><link>https://quietbo.com/2022/09/07/golang-%E7%B5%90%E6%A7%8B%E9%AB%94/</link><pubDate>Tue, 06 Sep 2022 17:07:53 +0000</pubDate><guid>https://quietbo.com/2022/09/07/golang-%E7%B5%90%E6%A7%8B%E9%AB%94/</guid><description>&lt;h2 id="定義實例化"&gt;定義&amp;amp;實例化
&lt;/h2&gt;&lt;p&gt;定義方式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;type 類別名 struct {
 名稱1 類型
 Age int
 Color Color //可定義別的結構體或自己
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;實例化方式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;var instance T
instance := new(T)
instance *T
instance := &amp;T{}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

//結構體
type User struct {
 Name string
 Age int
 Color Color //可定義別的結構體或自己
}

type Color struct {
 R, G, B string
}

func main() {


 var user User
 user.Age = 20
 user.Name = "bocky"
 user.Color.R = "red"
 print(user.Color.R, user.Age) // red20

 user := new(User)
 user.Age = 25
 user.Name = "Abby"

 user1 := &amp;User{}
 user1.Name = "Car"
 user1.Age = 30


 //下方利用function來實例化
 user2 := NewUser("NAME1", 100)
 fmt.Println(user2.Name) //NAME1
 fmt.Println(user2.Age) //100
}

func NewUser(name string, age int) *User {
 return &amp;User{
 Name: name,
 Age: age,
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初始化成員變量&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

type Person struct {
 name string
 chile *Person
}

type User struct {
 Name string
 Sex int
 Email string
 Mobile string
}

func main() {

 Person := &amp;Person{name: "奶奶", chile: &amp;Person{name: "媽媽", chile: &amp;Person{name: "我"}}}

 fmt.Println(Person.chile.chile.name) // 我

 user1 := User{
 "Bocky",
 1,
 "a123456@gmail.com",
 "0123456789",
 }
 fmt.Println(user1) //{Bocky 1 shty@gmail.com 0123456789}

 //定義完後馬上初始化
 user2 := &amp;struct { //1.定義
 id int
 name string
 }{ //2.初始化
 22222333333,
 "Amy",
 }
 fmt.Println(user2) //&amp;{22222333333 Amy}
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="go中的方法與接收器-必學"&gt;Go中的方法與接收器 (必學)
&lt;/h2&gt;&lt;p&gt;將函數與結構體綁定&lt;br&gt;
格式:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;func (接收器變量 接收器類型) 函數名(參數列表) (返回参数){
 函數體
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"


type User struct {
 Name string
 Age int
}

func main() {
 user1 := &amp;User{
 Name: "AAAA",
 Age: 30,
 }
 fmt.Println("===有指標的類型===")
 user1.PprintName() //Name: Bocky
 user1.PprintAge() //Age: 30
 user1.PprintName() //Name: BBB

 fmt.Println("===沒有指標類型===")

 user2 := &amp;User{
 Name: "AAAA",
 Age: 30,
 }
 user2.printName() //Name: AAAA
 user2.printAge()
 //Name: BBB
 //Age: 30
 user2.printName() //Name: AAAA
}

// 由此function調用, 可使用指針來修改值
func (user *User) PprintName() {
 fmt.Println("Name:", user.Name)
}

func (user *User) PprintAge() { // 使用*User 指針類型是可改值的
 user.Name = "BBB" // 原本是AAAA改成BBB
 fmt.Println("Age:", user.Age)
}

// 非指針類型的接收器
func (user User) printName() {
 fmt.Println("Name:", user.Name)
}
func (user User) printAge() { // 使用*User 指針類型是可改值的
 user.Name = "BBB"
 fmt.Println("Name:", user.Name) // 原本是AAAA改成BBB, Name: BBB
 fmt.Println("Age:", user.Age) //Age: 30
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;印出結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;===有指標的類型===
Name: AAAA
Age: 30
Name: BBB
===沒有指標類型===
Name: AAAA
Name: BBB
Age: 30
Name: AAAA&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] 函數, 匿名函數,閉包,可變參數,遞迴, 延遲執行</title><link>https://quietbo.com/2022/09/03/golang-%E5%87%BD%E6%95%B8-%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B8%E9%96%89%E5%8C%85%E5%8F%AF%E8%AE%8A%E5%8F%83%E6%95%B8%E9%81%9E%E8%BF%B4-%E5%BB%B6%E9%81%B2%E5%9F%B7%E8%A1%8C/</link><pubDate>Fri, 02 Sep 2022 18:55:39 +0000</pubDate><guid>https://quietbo.com/2022/09/03/golang-%E5%87%BD%E6%95%B8-%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B8%E9%96%89%E5%8C%85%E5%8F%AF%E8%AE%8A%E5%8F%83%E6%95%B8%E9%81%9E%E8%BF%B4-%E5%BB%B6%E9%81%B2%E5%9F%B7%E8%A1%8C/</guid><description>&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#%E5%87%BD%E6%95%B8" &gt;函數&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B8" &gt;匿名函數&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-3" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#%E9%96%89%E5%8C%85" &gt;閉包&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-4" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#%E5%8F%AF%E8%AE%8A%E5%8F%83%E6%95%B8" &gt;可變參數&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-5" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#%E8%A8%88%E7%AE%97%E5%87%BD%E6%95%B8%E6%99%82%E9%96%93" &gt;計算函數時間&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-6" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#%E9%81%9E%E8%BF%B4" &gt;遞迴&lt;/a&gt;
 &lt;/li&gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-7" href="https://quietbo.com/2022/09/03/golang-%e5%87%bd%e6%95%b8-%e5%8c%bf%e5%90%8d%e5%87%bd%e6%95%b8%e9%96%89%e5%8c%85%e5%8f%af%e8%ae%8a%e5%8f%83%e6%95%b8%e9%81%9e%e8%bf%b4-%e5%bb%b6%e9%81%b2%e5%9f%b7%e8%a1%8c/#defer_%E5%BB%B6%E9%81%B2%E5%9F%B7%E8%A1%8C" &gt;defer 延遲執行&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="函數"&gt;&lt;span class="ez-toc-section" id="%E5%87%BD%E6%95%B8"&gt;&lt;/span&gt;函數&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;輸入的參數可多個, 返回也可多個&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;func 函數名(參數)(返回值){
 函數體
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {

 fmt.Println(sum(2, 3)) //5
 x, y := getXYValue()
 fmt.Printf("x:%d y:%d", x, y) //x:1 y:2

 var f func() //指定function類型
 f = process //把process這個func指定給f
 f() // 調用f等於調用process
}

func sum(x, y int) int {
 return x + y
}

func getXYValue() (x, y int) {
 x = 1
 y = 2
 return x, y
}

func process() {
 fmt.Println("use process function")
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="匿名函數"&gt;&lt;span class="ez-toc-section" id="%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B8"&gt;&lt;/span&gt;匿名函數&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 //匿名函數

 f := func(name string) {
 fmt.Println("hello,", name)
 }
 f("bocky") //hello, bocky
 fmt.Println("===")

 iterator([]int{1, 2, 3, 4, 5, 6}, func(value int) { //函數沒有名稱
 fmt.Println(value)
 })
}

func iterator(arr []int, ff func(int)) { // 這裡的函數是有名稱ff
 for _, value := range arr {
 ff(value)
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="閉包"&gt;&lt;span class="ez-toc-section" id="%E9%96%89%E5%8C%85"&gt;&lt;/span&gt;閉包&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;閉包 = 函數+引用環境&lt;/p&gt;
&lt;p&gt;範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 //str := "Bocky" // IDE會出現str declared but not used
 f := func() {
 str := "Abby"
 fmt.Println(str) //Abby
 }
 f()

 // 閉包擁有記憶性
 fmt.Println("======")
 add1 := add(1)
 fmt.Println(add1()) //2
 fmt.Println(add1()) //3
 fmt.Printf("%p\n", &amp;add1) //0xc000006030

 fmt.Println("======")
 add2 := add(200)
 fmt.Println(add2()) //201
 fmt.Println(add2()) //202
 fmt.Printf("%p\n", &amp;add2) //0xc000006038

 fmt.Println("======")
 bocky := user("bocky")
 name, hp := bocky()
 fmt.Println(name, hp) //bocky 1000

 fmt.Println("======")
 amy := user("amy")
 name2, hp2 := amy()
 fmt.Println(name2, hp2) //amy 1000
}

func add(v1 int) func() int {
 return func() int {
 v1++
 return v1
 }
}

func user(name string) func() (string, int) {
 hp := 1000
 return func() (string, int) {
 return name, hp
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="可變參數"&gt;&lt;span class="ez-toc-section" id="%E5%8F%AF%E8%AE%8A%E5%8F%83%E6%95%B8"&gt;&lt;/span&gt;可變參數&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;在實際開發中，總有一些函數的參數個數是在編碼過程中無法確定的，&lt;br&gt;
當有狀況是需要實現類似的接口時，就會用到”可變參數”了。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "bytes"
 "fmt"
)

func main() {
 //可變參數
 funx1(1)
 funx1(1, 2, 3, 5)

 funx2(11) //11 int
 funx2("1234") //1234 string
 funx2(1.23) //1.23 default
 funx2(func() () { return }) //0x96ca00 default

 fmt.Println("=======")
 fmt.Println(funx3("hello "))
 fmt.Println(funx3("hello ", "I'm ")) //hello I'm
 fmt.Println(funx3("hello ", "I'm ", "Bocky!")) //hello I'm Bocky!



 fmt.Println("=======")
 Tprint("A","B","C")
}

func funx1(args ...int) { //不確定會傳多少個int的時候可以使用...但一定要是int類型
 for _, arg := range args {
 fmt.Println(arg)
 }
}

func funx2(args ...interface{}) { //任一類型的可變參數
 for _, arg := range args {
 switch arg.(type) {
 case int:
 fmt.Println(arg, "int")
 case string:
 fmt.Println(arg, "string")
 case float32:
 fmt.Println(arg, "float32")
 default:
 fmt.Println(arg, "default")
 }
 }
}

func funx3(strs ...string) string {
 var b bytes.Buffer
 for _, s := range strs { // 依序遍歷strs內的string
 b.WriteString(s)
 }
 return b.String()
}

//下方Tprint會call funx4來執行print的動作
func Tprint(params ...interface{}) {
 funx4(params)
}
func funx4(params ...interface{}) {
 for _, value := range params {
 fmt.Println(value)
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="計算函數時間"&gt;&lt;span class="ez-toc-section" id="%E8%A8%88%E7%AE%97%E5%87%BD%E6%95%B8%E6%99%82%E9%96%93"&gt;&lt;/span&gt;計算函數時間&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;想要獲取計算某個任務從開始到結束的運行時間，我們可以使用time包中的Slice函數，用法:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;func Since (t Time) Duration&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;t是時間值。&lt;br&gt;
&lt;strong&gt;此方法是time.Now().Sub(t)的快捷方式&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
 "time"
)

func main() {
 //func Since(t Time)Duration
 //time.Now().sub(t
 testTime()
}

func testTime() {

 start := time.Now()
 sum := 0
 for i := 0; i &amp;lt; 1000000000; i++ {
 sum++
 }
 duration := time.Since(start)
 fmt.Println("function執行時間:", duration)
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="遞迴"&gt;&lt;span class="ez-toc-section" id="%E9%81%9E%E8%BF%B4"&gt;&lt;/span&gt;遞迴&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;費波那契數列&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;1,1,2,3,5,8,13 ,...&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 //遞迴

 result := 0
 for i := 1; i &amp;lt;= 10; i++ {
 result = fibonacci(i)
 fmt.Printf("fibonacci(%2d) -&amp;gt; %3d\n", i, result)
 }
}

func fibonacci(n int) (rtn int) {
 if n &amp;lt;= 2 {
 rtn = 1
 } else {
 rtn = fibonacci(n-1) + fibonacci(n-2)
 }
 return
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="defer-延遲執行"&gt;&lt;span class="ez-toc-section" id="defer_%E5%BB%B6%E9%81%B2%E5%9F%B7%E8%A1%8C"&gt;&lt;/span&gt;defer 延遲執行&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 用於資源的釋放，會在函數返回之前進行調用，簡單來說就是宣告 function &amp;#8220;結束前&amp;#8221;的動作。
 &lt;/li&gt;
 &lt;li&gt;
 先進後出
 &lt;/li&gt;
 &lt;li&gt;
 會保留當下狀態
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;簡單的範例:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
)


func main() {
 fmt.Println("defer start")
 defer fmt.Println(1)
 defer fmt.Println(2)
 defer fmt.Println(3)
 fmt.Println("defer stop")
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;defer start
defer stop
3
2
1&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
)

func main() {
 num := 1
 x := addOne(num)

 fmt.Printf("Result is %d\n",x)
}


func closeProcess() {
 fmt.Println("close process")
}
func addOne(x int) int {
 fmt.Println("Start process")
 defer closeProcess() // function結束前返回
 if x &amp;gt; 2 {
 fmt.Println("x &amp;gt; 2")
 return x * 20
 } else {
 fmt.Println("x &amp;lt;=2")
 return x + 1
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;Start process
x &amp;lt;=2
close process
Result is 2&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] List</title><link>https://quietbo.com/2022/09/01/golang-list/</link><pubDate>Thu, 01 Sep 2022 09:44:37 +0000</pubDate><guid>https://quietbo.com/2022/09/01/golang-list/</guid><description>&lt;p&gt;List由多個節點所組成的, 節點之間透過一些變數紀錄彼此的關係&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;a -&amp;gt; next -&amp;gt; b -&amp;gt; next -&amp;gt; c
a &amp;lt;- pre &amp;lt;- b &amp;lt;- pre &amp;lt;- c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;宣告方式&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;name:=list.New()
//var name list.List&lt;/code&gt;&lt;/pre&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 PushBack:插入元素直接放入結尾
 &lt;/li&gt;
 &lt;li&gt;
 PushFront:插入元素直接放入開頭
 &lt;/li&gt;
 &lt;li&gt;
 InsertBefore:被標記的元素前增加元素
 &lt;/li&gt;
 &lt;li&gt;
 InsertAfter:被標記的元素後增加元素
 &lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "container/list"
 "fmt"
)

func main() {
 //List




 list1 := list.New()
 list1.PushBack("Back_1") //插入元素直接放入結尾
 list1.PushFront(111) //插入元素直接放入最前 111 Back_1
 list1.PushBack("Back_2") //插入元素直接放入結尾 111 Back_1 Back_2

 el := list1.PushBack("Back_3") // 111 Back_1 Back_2 Back_3
 //在Back_3的後方加入After
 list1.InsertAfter("After", el) // 111 Back_1 Back_2 Back_3 After
 // 在Back_3的前方加入Before
 list1.InsertBefore("Before", el) // 111 Back_1 Back_2 Before Back_3 After

 // 移除 Back_3
 //list1.Remove(el)
 for i := list1.Front(); i != nil; i = i.Next() {
 fmt.Println(i.Value)
 }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顯示結果&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=" line-numbers"&gt;111
Back_1
Back_2
Before
Back_3
After&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] map</title><link>https://quietbo.com/2022/09/01/golang-map%E9%9B%86%E5%90%88/</link><pubDate>Thu, 01 Sep 2022 08:30:28 +0000</pubDate><guid>https://quietbo.com/2022/09/01/golang-map%E9%9B%86%E5%90%88/</guid><description>&lt;p&gt;宣告方式:&lt;/p&gt;
&lt;p&gt;var name map[keyType]valueType&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;var map1 map[string]int

// 使用 make 建立 Map。
// Key 的型別是 string，Value 是 int
map2 := make(map[string]int)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;賦值與刪除&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 // map 無序的鍵, 無法決定它的返回順序。通過key來檢索數據

 //var name map[keyType]valueType

 var map1 map[string]int
 map1 = map[string]int{"A": 1, "B": 2}
 fmt.Println(map1["B"]) //2
 //map1["C"] = "3" //會報錯

 map2 := make(map[string]float32)
 map2["k1"] = 2.345
 map2["k2"] = 1.3
 fmt.Println(map2["k1"]) // 2.345

 // 提前指定空間
 //map3 := make(map[string]int, 10)

 for k, v := range map1 {
 fmt.Println(k, v)
 //A 1
 //B 2
 }

 // 刪除方式
 // delete(map, key)
 delete(map2, "k1")
 for k, v := range map2 {
 fmt.Println(k, v)
 //k2 1.3
 }

}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] 陣列 (array) 和切片 (slice)</title><link>https://quietbo.com/2022/09/01/golang-%E9%99%A3%E5%88%97-array-%E5%92%8C%E5%88%87%E7%89%87-slice/</link><pubDate>Wed, 31 Aug 2022 19:07:12 +0000</pubDate><guid>https://quietbo.com/2022/09/01/golang-%E9%99%A3%E5%88%97-array-%E5%92%8C%E5%88%87%E7%89%87-slice/</guid><description>&lt;h2 id="陣列"&gt;陣列
&lt;/h2&gt;&lt;p&gt;陣列索引是從 0 開始, 以索引 (index) 對陣列賦值。&lt;br&gt;
附上Code:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {

 fmt.Println("===一維數組===")
 //var
 var arr [3]int
 fmt.Println(arr[0])
 fmt.Println(len(arr))
 fmt.Println(arr[len(arr)-1])

 //for _, v := range arr{
 // fmt.Printf("%d \n", v)
 //}
 for i, v := range arr {
 fmt.Printf("%d %d \n", i, v)
 }
 //0
 //3
 //0
 //0 0
 //1 0
 //2 0

 var arr1 [3]int = [3]int{1, 3, 5}
 fmt.Println(arr1[2]) //5

 arr2 := [...]int{1, 3, 5}
 fmt.Println(arr2[2]) //5

 fmt.Println(arr1 == arr2) //true

 for i, v := range arr2 {
 fmt.Printf("%d %d \n", i, v)
 }
 //0 1
 //1 3
 //2 5

 fmt.Println("===多維數組===")

 //var arr3 [4][2]int //宣告方式
 arr3 := [4][2]int{{11, 22}, {12, 23}, {45, 62}, {83, 26}}
 fmt.Println(arr3[0][0]) //11
 fmt.Println(arr3[3][1]) //26
 //fmt.Println(arr3[4][2]) //超過會報錯

 fmt.Println("======")
 arr4 := [4][2]int{1: {11, 22}, 3: {31, 36}}
 fmt.Println(arr4[0][0]) //0
 fmt.Println(arr4[1][0]) //11
 fmt.Println(arr4[2][0]) //0
 fmt.Println(arr4[3][1]) //36

 fmt.Println("======")

 arr5 := [4][3]int{1: {0: 100}, 3: {2: 33}}
 fmt.Println(arr5[1][0]) //100
 fmt.Println(arr5[3][2]) //33
 fmt.Println(arr5[1][1]) //0

 arr5[1][1] = 66 //賦值
 fmt.Println(arr5[1][1]) //66
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="切片"&gt;切片
&lt;/h2&gt;&lt;p&gt;使用 make() 函數來創建切片:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code class=""&gt;var slice1 []type = make([]type, len)
// 也可以簡寫為
slice1 := make([]type, len)
//slice11 := make([]int, len)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
)

func main() {

 //slice [開始位置:結束位置]
 var arr = [3]int{1, 2, 3}
 fmt.Println(arr, arr[1:2]) //[1 2 3] [2]

 var arr1 = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 fmt.Println(arr1[2:5]) // [3 4 5]
 fmt.Println(arr1[:5]) //[1 2 3 4 5]

 fmt.Println(arr1[5:]) //[6 7 8 9 10]
 fmt.Println(arr1[:]) //[1 2 3 4 5 6 7 8 9 10] //跟 [0:10], [:10]一樣
 fmt.Println(arr1[0:0]) //[0]

 //var name[]Type
 //var stringSlice []string
 //var numberSlice []int
 //var numberEmptySlice []int

 //make([]Type, size. cap) // make 並不會回傳指標
 a := make([]int, 2)
 b := make([]int, 2, 10)
 fmt.Println(a, b) //[0 0] [0 0]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;append 添加元素&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
)

func main() {
 var a, b []int
 a = append(a, 1) // 追加一個元素
 fmt.Println(a) //[1]

 b = append(b, 1, 2, 3) // 追加三個元素
 fmt.Println(b) //[1 2 3]

 b = append(b, []int{4, 6, 8}...) // 從後方添加
 fmt.Println(b) //[1 2 3 4 6 8]

 var sli []int

 for i := 0; i &amp;lt; 10; i++ {
 sli = append(sli, i)
 fmt.Printf("長度:%d,容量:%d,地址:%p\n", len(sli), cap(sli), sli)
 }
 //長度:1,容量:1,地址:0xc00000e128
 //長度:2,容量:2,地址:0xc00000e130
 //長度:3,容量:4,地址:0xc0000141e0
 //長度:4,容量:4,地址:0xc0000141e0
 //長度:5,容量:8,地址:0xc000012280
 //長度:6,容量:8,地址:0xc000012280
 //長度:7,容量:8,地址:0xc000012280
 //長度:8,容量:8,地址:0xc000012280
 //長度:9,容量:16,地址:0xc00010c000
 //長度:10,容量:16,地址:0xc00010c000

 var r = []int{1, 2, 3}
 r = append([]int{0}, r...) //從前面加了0
 fmt.Println(r) //[0 1 2 3]

 r = append([]int{-4, -3, -2, -1}, r...)
 fmt.Println(r) //[-4 -3 -2 -1 0 1 2 3]
 //盡量不要從前面去加

 // 一般容量會大於長度
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="copy"&gt;copy
&lt;/h3&gt;&lt;p&gt;copy() 可以將一個數組切片複製到另一個數組切片中，如果加入的兩個數組切片不一樣大，就會按照其中較小的那個數組切片的元素個數進行複制。&lt;/p&gt;
&lt;p&gt;範例1:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import (
 "fmt"
)

func main() {
 // copy(目標切片, 源切片)類型

 slice1 := []int{1, 2, 3, 4, 5, 6}
 slice2 := []int{7, 8, 9}
 slice3 := []int{9, 8, 7}
 //copy(slice1, slice2) //複製 7 8 9 到s1 的1 2 3 位置
 copy(slice1, slice2)
 fmt.Println(slice1) //[7 8 9 4 5 6]
 fmt.Println(slice2) //[7 8 9]
 fmt.Println("=========")
 // 與長度有關, 會將 7 8 9 複製到slice3
 copy(slice3, slice1)
 fmt.Printf("slice1:%d, slice3:%d \n", slice1, slice3)
 // slice1:[7 8 9 4 5 6], slice3:[7 8 9][7 8 9]

}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 // copy(目標切片, 源切片)類型
 const len = 10 //const常量是一個簡單值的標識符，在程序運行時，不會被修改的量。
 //創建切片var slice1 []type = make([]type, len)
 slice11 := make([]int, len)
 for i := 0; i &amp;lt; len; i++ {
 slice11[i] = i
 }
 slice33 := slice11
 slice22 := make([]int, len)
 copy(slice22, slice11)
 fmt.Println(slice11) //[0 1 2 3 4 5 6 7 8 9]
 fmt.Println(slice22) //[0 1 2 3 4 5 6 7 8 9]
 fmt.Println(slice33) //[0 1 2 3 4 5 6 7 8 9]

 slice11[0] = 999
 fmt.Println(slice11[0]) //999
 fmt.Println(slice22[0]) //0 不受影響
 fmt.Println(slice33[0]) //999

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;刪除元素&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {

 //刪除元素

 //方法
 var a = []int{1, 2, 3}
 a = a[2:]
 fmt.Println(a) //[3]

 //方法-append
 var b = []int{1, 2, 3, 4, 5, 6}
 fmt.Println(b[:1]) //[1]
 b = append(b[:1], b[4:]...)
 fmt.Println(b) //[1 5 6]

 //方法-copy
 var c = []int{1, 2, 3, 4, 5, 6, 7}
 c = c[:copy(c, c[3:])] // 與append類似
 fmt.Println(c) // [4 5 6 7]

 //試者了解這取值的過程
 fmt.Println(c) //[4 5 6 7 5 6 7]
 fmt.Println(c[3:]) //[4 5 6 7]
 fmt.Println(copy(c, c[3:])) //4
 fmt.Println(c[:4]) //[4 5 6 7]

 // 方法 - append
 var d = []int{1, 2, 3, 4, 5}
 fmt.Println(d[3+1:]) //[5]
 fmt.Println(d[:3]) //[1 2 3]
 // d = append(d[:N], d[N+1:]...)
 d = append(d[:3], d[3+1:]...)
 fmt.Println(d) //[1 2 3 5]

 // 方法 - copy
 var e = []int{1, 2, 3, 4, 5}
 e = e[:2+copy(e[2:], e[2+1:])]
 fmt.Println(e)//[1 2 4 5]

 //方法-slice

 slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8}
 index := 2
 fmt.Println(slice1[:index], slice1[index+1:]) //[1 2] [4 5 6 7 8]

 slice1 = append(slice1[:index], slice1[index+1:]...)
 fmt.Println(slice1) //[1 2 4 5 6 7 8]

}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] 指標</title><link>https://quietbo.com/2022/08/26/golang-%E6%8C%87%E6%A8%99/</link><pubDate>Thu, 25 Aug 2022 17:38:38 +0000</pubDate><guid>https://quietbo.com/2022/08/26/golang-%E6%8C%87%E6%A8%99/</guid><description>&lt;p&gt;*int : 宣告的指標整數&lt;/p&gt;
&lt;p&gt;&amp;amp;變數名 : 拿記憶體位置&lt;/p&gt;
&lt;p&gt;fmt.Printf: &lt;a class="link" href="https://pkg.go.dev/fmt" target="_blank" rel="noopener"
 &gt;格式化輸出&lt;/a&gt;&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"


func main(){
 var a int = 100
 var s string = "hello"

 fmt.Print(a)
 fmt.Print(s)
 fmt.Println("%p %p", &amp;a, &amp;s)

 var address ="Bocky address"

 ptr := &amp;address
 fmt.Printf("Address =%p \n", ptr) //Address =0xc000010260

 value := *ptr
 fmt.Printf("value Type: %T \n", value) // value Type: string
 fmt.Printf("value value: %s \n", value) //value value: Bocky address

 aa, bb := 10, 100
 swap(&amp;aa, &amp;bb)
 fmt.Println(aa,bb)
}



func swap(m, n *int){

 // s =10
 s := *m

 // m 100 n 100
 *m = *n

 // n 10
 *n = s
}&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] go run: cannot run non-main package(解決)</title><link>https://quietbo.com/2022/08/08/golang-go-run-cannot-run-non-main-package%E8%A7%A3%E6%B1%BA/</link><pubDate>Mon, 08 Aug 2022 08:39:55 +0000</pubDate><guid>https://quietbo.com/2022/08/08/golang-go-run-cannot-run-non-main-package%E8%A7%A3%E6%B1%BA/</guid><description>&lt;p&gt;寫了第一個go程序，很簡單，就是一個簡單的輸出語句，但是確報了&lt;br&gt;
go run: cannot run non-main package 的錯誤信息，代碼如下：&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package example

import "fmt"

const englishHelloPrefix = "Hello, "

func Hello(name string) string {
 return englishHelloPrefix + name
}

func main() {
 fmt.Println(Hello("world"))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在終端機執行了main.go的檔案但出現錯誤&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash line-numbers"&gt;$ go run main.go 
go run: cannot run non-main package&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;main方法只能放在package main中，go run 是執行命令，必須要一個main用來調用&lt;/p&gt;
&lt;p&gt;把第一行改成下方就可以了&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[Golang] 安裝 (Windows &amp; ubuntu20.04)</title><link>https://quietbo.com/2022/07/21/golang-%E5%AE%89%E8%A3%9D-windows-ubuntu20-04/</link><pubDate>Thu, 21 Jul 2022 15:59:38 +0000</pubDate><guid>https://quietbo.com/2022/07/21/golang-%E5%AE%89%E8%A3%9D-windows-ubuntu20-04/</guid><description>&lt;div id="ez-toc-container" class="ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction"&gt;
 &lt;div class="ez-toc-title-container"&gt;
 &lt;p class="ez-toc-title" style="cursor:inherit"&gt;
 Table of Contents
 &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span class=&amp;quot;ez-toc-title-toggle&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle&amp;quot; aria-label=&amp;quot;顯示/隱藏內容目錄&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-js-icon-con&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;eztoc-hide&amp;quot; style=&amp;quot;display:none;&amp;quot;&amp;gt;Toggle&amp;lt;/span&amp;gt;&amp;lt;span class=&amp;quot;ez-toc-icon-toggle-span&amp;quot;&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; class=&amp;quot;list-377408&amp;quot; width=&amp;quot;20px&amp;quot; height=&amp;quot;20px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;svg style=&amp;quot;fill: #999;color:#999&amp;quot; class=&amp;quot;arrow-unsorted-368013&amp;quot; xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;10px&amp;quot; height=&amp;quot;10px&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; version=&amp;quot;1.2&amp;quot; baseProfile=&amp;quot;tiny&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;&lt;nav&gt;
 &lt;ul class='ez-toc-list ez-toc-list-level-1 ' &gt;
 &lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-1" href="https://quietbo.com/2022/07/21/golang-%e5%ae%89%e8%a3%9d-windows-ubuntu20-04/#Windows%E5%AE%89%E8%A3%9D" &gt;Windows安裝&lt;/a&gt;&lt;ul class='ez-toc-list-level-3' &gt;
 &lt;li class='ez-toc-heading-level-3'&gt;
 &lt;a class="ez-toc-link ez-toc-heading-2" href="https://quietbo.com/2022/07/21/golang-%e5%ae%89%e8%a3%9d-windows-ubuntu20-04/#%E5%9F%B7%E8%A1%8C%E7%AC%AC%E4%B8%80%E6%94%AF%E7%A8%8B%E5%BC%8Fhellogo" &gt;執行第一支程式hello.go&lt;/a&gt;
 &lt;/li&gt;
 &lt;/ul&gt;
 &lt;/li&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-3&amp;quot; href=&amp;quot;https://quietbo.com/2022/07/21/golang-%e5%ae%89%e8%a3%9d-windows-ubuntu20-04/#ubuntu_%E5%AE%89%E8%A3%9D_golang_118&amp;quot; &amp;gt;[ubuntu] 安裝 golang 1.18&amp;lt;/a&amp;gt;&amp;lt;ul class='ez-toc-list-level-3' &amp;gt;
 &amp;lt;li class='ez-toc-heading-level-3'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-4&amp;quot; href=&amp;quot;https://quietbo.com/2022/07/21/golang-%e5%ae%89%e8%a3%9d-windows-ubuntu20-04/#%E5%B7%B2%E8%A7%A3%E6%B1%BA_%E9%97%9C%E6%8E%89%E7%B5%82%E7%AB%AF%E6%A9%9F%E6%89%BE%E4%B8%8D%E5%88%B0go&amp;quot; &amp;gt;[已解決] 關掉終端機找不到go&amp;lt;/a&amp;gt;
 &amp;lt;/li&amp;gt;
 &amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-3'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-5&amp;quot; href=&amp;quot;https://quietbo.com/2022/07/21/golang-%e5%ae%89%e8%a3%9d-windows-ubuntu20-04/#%E5%9F%B7%E8%A1%8Cgo%E6%AA%94%E6%A1%88&amp;quot; &amp;gt;執行go檔案&amp;lt;/a&amp;gt;
 &amp;lt;/li&amp;gt;
 &amp;lt;/ul&amp;gt;
&amp;lt;/li&amp;gt;

&amp;lt;li class='ez-toc-page-1 ez-toc-heading-level-2'&amp;gt;
 &amp;lt;a class=&amp;quot;ez-toc-link ez-toc-heading-6&amp;quot; href=&amp;quot;https://quietbo.com/2022/07/21/golang-%e5%ae%89%e8%a3%9d-windows-ubuntu20-04/#%E6%A8%99%E6%BA%96%E5%91%BD%E4%BB%A4_%E2%80%93_run_%E8%88%87_build%E5%B7%AE%E7%95%B0&amp;quot; &amp;gt;標準命令 &amp;amp;#8211; run 與 build差異&amp;lt;/a&amp;gt;
&amp;lt;/li&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
 &lt;/ul&gt;&lt;/nav&gt;
&lt;/div&gt;
&lt;h2 id="windows安裝"&gt;&lt;span class="ez-toc-section" id="Windows%E5%AE%89%E8%A3%9D"&gt;&lt;/span&gt;Windows安裝&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;以下為安裝連結:&lt;br&gt;
&lt;a class="link" href="https://go.dev/" target="_blank" rel="noopener"
 &gt;安裝Golang&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://code.visualstudio.com/" target="_blank" rel="noopener"
 &gt;VSCode&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="執行第一支程式hellogo"&gt;&lt;span class="ez-toc-section" id="%E5%9F%B7%E8%A1%8C%E7%AC%AC%E4%B8%80%E6%94%AF%E7%A8%8B%E5%BC%8Fhellogo"&gt;&lt;/span&gt;執行第一支程式hello.go&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;p&gt;下方為hello.go內的code&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 fmt.Println("Hello Golang")
}

// 1.撰寫程式 &amp;gt; 建置(build) &amp;gt; 執行程式
// 建置: go build 程式檔案的名稱

// 2. 執行程式: 輸入執行檔的檔名&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打開終端機執行:&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="basic" class="language-basic"&gt;$ go build hello.go&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;會產生hello.exe, 在終端機執行hello&lt;br&gt;
如果出現錯誤訊息&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;Suggestion [3,General]: 找不到 hello 命令，但它確實存在於目前的位置。Windows PowerShell 預設並不會從目前的位置載入命令。如果您信任這個命令，請改為輸入 ".\hello"。&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;請改使用./hello&lt;/p&gt;
&lt;p&gt;補充:&lt;br&gt;
若是package main出現紅色底線, 重新開機即可。&lt;/p&gt;
&lt;h2 id="ubuntu-安裝-golang-118"&gt;&lt;span class="ez-toc-section" id="ubuntu_%E5%AE%89%E8%A3%9D_golang_118"&gt;&lt;/span&gt;[ubuntu] 安裝 golang 1.18&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;p&gt;下載golang壓縮檔(如果要其他版本則自行把18換成其他版本號)&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;wget https://dl.google.com/go/go1.18.linux-amd64.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的命令安裝了 Golang v1.13，大多數用戶更喜歡更新版本的 Golang，當新版本出現時會不斷更新。 實現此目的的最佳方法是安裝 PPA。&lt;/p&gt;
&lt;p&gt;解壓縮&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;sudo tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成後ls /usr/local會多一個go的目錄&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ ls /usr/local
bin etc games go include lib man sbin share src&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用指令vi /etc/profile進到檔案內, 在最下方添加,&lt;br&gt;
目的是在系統環境變量PATH中增加go的路徑&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ vi /etc/profile
export PATH=$PATH:/usr/local/go/bin&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;儲存並離開,使用下方指令立即生效&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;source /etc/profile&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;輸入go version查看版本號&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ go version
go version go1.18 linux/amd64&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="已解決-關掉終端機找不到go"&gt;&lt;span class="ez-toc-section" id="%E5%B7%B2%E8%A7%A3%E6%B1%BA_%E9%97%9C%E6%8E%89%E7%B5%82%E7%AB%AF%E6%A9%9F%E6%89%BE%E4%B8%8D%E5%88%B0go"&gt;&lt;/span&gt;[已解決] 關掉終端機找不到go&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;p&gt;開啟profile檔案&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;nano $HOME/.profile&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然後將以下行貼上到檔案中並儲存。&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;export PATH=$PATH:/usr/local/go/binb&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成後，執行以下命令以完成安裝&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ source ~/.profile
$ go version&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;補充:&lt;br&gt;
加入環境變量後但仍出現找不到go, 或是關閉終端機就會出現找不到go, 重新開啟VM試試看&lt;br&gt;
&lt;a class="link" href="https://volvootofinans.com/zh-TW/how-to-install-go-on-ubuntu-20-04-18-04.html" target="_blank" rel="noopener"
 &gt;參考此處&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="執行go檔案"&gt;&lt;span class="ez-toc-section" id="%E5%9F%B7%E8%A1%8Cgo%E6%AA%94%E6%A1%88"&gt;&lt;/span&gt;執行go檔案&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h3&gt;&lt;p&gt;上方安裝及環境沒問題後, 可執行一隻hello.go試試看&lt;/p&gt;
&lt;p&gt;下方儲存名稱為main.go&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="go" class="language-go line-numbers"&gt;package main

import "fmt"

func main() {
 fmt.Println("Hello, World")
 fmt.Println("哈囉！世界！")
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打開終端機輸入&lt;/p&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ go run main.go
Hello, World
哈囉！世界！&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a class="link" href="https://go.dev/doc/code" target="_blank" rel="noopener"
 &gt;連結&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="標準命令-8211-run-與-build差異"&gt;&lt;span class="ez-toc-section" id="%E6%A8%99%E6%BA%96%E5%91%BD%E4%BB%A4_%E2%80%93_run_%E8%88%87_build%E5%B7%AE%E7%95%B0"&gt;&lt;/span&gt;標準命令 – run 與 build差異&lt;span class="ez-toc-section-end"&gt;&lt;/span&gt;
&lt;/h2&gt;&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 build
 &lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ go build 檔案名.go&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果沒有錯誤就產生執行檔於當前目錄, 例如執行main.go成功就會出現一個main.exe檔案在同樣路徑下&lt;/p&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 run
 &lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="wp-block-code"&gt;&lt;code lang="bash" class="language-bash"&gt;$ go run 檔案名.go&lt;/code&gt;&lt;/pre&gt;
&lt;ul class="wp-block-list"&gt;
 &lt;li&gt;
 直接執行golang code
 &lt;/li&gt;
 &lt;li&gt;
 直接在命令行輸出程序執行結果，方便用戶調試，本質上也是先編譯再執行
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可參考更多資訊:&lt;a class="link" href="https://blog.csdn.net/wohu1104/article/details/106295007" target="_blank" rel="noopener"
 &gt;Go 學習筆記（37）— 標準命令（go build 跨平台編譯、交叉編譯、go clean、go run、go fmt、go install、go get）&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>