web框架
流行度排行
https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#popularity
beego
https://beego.me/products
echo
https://echo.labstack.com/
gin
go社區檔案
https://learnku.com/docs/gin-gonic/2019
看云gin檔案
https://www.kancloud.cn/shuangdeyu/gin_book/949418
gin快速使用
https://www.jianshu.com/p/98965b3ff638
gin-admin-vue
https://www.gin-vue-admin.com/docs/gorm
官網
https://golang.org/dl/
中文官網
https://go-zh.org/pkg/
go常用庫
https://github.com/jobbole/awesome-go-cn
查看版本號
go version
查看env
go env
拉不下來包
export GOPATH=/usr/local/go/bin
export GOPROXY=https://goproxy.io
export PATH=$PATH:$GOPATH
export GO111MODULE=on
開啟module
go env -w GO111MODULE=on
設定代理
go env -w GOPROXY=https://goproxy.io,direct
微服務框架
go-kit
go micro
go-zero
常用網址
go基礎知識
go基礎知識v1
go基礎知識v2---micro
菜鳥GO
檔案和技術論壇
gomod 詳細使用
go官網庫
go官方pkg中文
github對pgk的使用例子
go mod使用

基本資料型別

字串操作

本地gorm struct生成
https://github.com/xxjwxc/gormt.git
本地struct生成
https://github.com/hantmac/fuckdb.git
1 使用docker-composer方式啟動
2 遇到docker容器不能鏈接本地mysql的時候
在本地mysql
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES
struct 生成
go get -u github.com/gohouse/converter
err := converter.NewTable2Struct().
SavePath("./model.go").
Dsn("root:root@tcp(127.0.0.1:3306)/foroo_beta_shopify?charset=utf8").
TagKey("db").
EnableJsonTag(true).
Table("fr_store").
Run()
fmt.Println(err)
return
基礎
變數或者方法使用小寫相當于protect 首字母大寫 相當于public
使用+來拼接字串
變數宣告 var age int;
常量中的資料型別只可以是布爾型、數字型(整數型、浮點型和復數)和字串型,
可以將 var f string = "Runoob" 簡寫為 f := "Runoob":
函式外的每個陳述句都必須以關鍵字開始(var、const、func等)
:=不能使用在函式外,
_多用于占位,表示忽略值,import _ "./hello" 用_占位只會執行匯入包內的init,其他方法都不能呼叫
iota是go語言的常量計數器,只能在常量的運算式中使用
strconv.Itoa(97) 將一個數字轉成字串型別 string(97)go自帶的會把數字轉換成對應的ascii碼
const (
n1 = iota //0
n2 //1
n3 //2
n4 //3
)
map、slice、chan、指標、interface默認以參考的方式傳遞,
互斥鎖 var lock sync.Mutex
var x int64
var wg sync.WaitGroup
var lock sync.Mutex
func add() {
for i := 0; i < 5000; i++ {
lock.Lock() // 加鎖
x = x + 1
lock.Unlock() // 解鎖
}
wg.Done()
}
func main() {
wg.Add(2)
go add()
go add()
wg.Wait()
fmt.Println(x)
}
讀寫互斥鎖 需要注意的是讀寫鎖非常適合讀多寫少的場景,如果讀和寫的操作差別不大,讀寫鎖的優勢就發揮不出來,
var (
x int64
wg sync.WaitGroup
lock sync.Mutex
rwlock sync.RWMutex
)
func write() {
// lock.Lock() // 加互斥鎖
rwlock.Lock() // 加寫鎖
x = x + 1
time.Sleep(10 * time.Millisecond) // 假設讀操作耗時10毫秒
rwlock.Unlock() // 解寫鎖
// lock.Unlock() // 解互斥鎖
wg.Done()
}
func read() {
// lock.Lock() // 加互斥鎖
rwlock.RLock() // 加讀鎖
time.Sleep(time.Millisecond) // 假設讀操作耗時1毫秒
rwlock.RUnlock() // 解讀鎖
// lock.Unlock() // 解互斥鎖
wg.Done()
}
func main() {
start := time.Now()
for i := 0; i < 10; i++ {
wg.Add(1)
go write()
}
for i := 0; i < 1000; i++ {
wg.Add(1)
go read()
}
wg.Wait()
end := time.Now()
fmt.Println(end.Sub(start))
}
sync.Once其實內部包含一個互斥鎖和一個布林值,互斥鎖保證布林值和資料的安全,而布林值用來記錄初始化是否完成,這樣設計就能保證初始化操作的時候是并發安全的并且初始化操作也不會被執行多次,
var icons map[string]image.Image
var loadIconsOnce sync.Once
func loadIcons() {
icons = map[string]image.Image{
"left": loadIcon("left.png"),
"up": loadIcon("up.png"),
"right": loadIcon("right.png"),
"down": loadIcon("down.png"),
}
}
// Icon 是并發安全的
func Icon(name string) image.Image {
loadIconsOnce.Do(loadIcons)
return icons[name]
}
goroutine高并發下 操作map 要用 sync.Map 來操作
//sync.Map內置了諸如Store、Load、LoadOrStore、Delete、Range等操作方法
var m = sync.Map{}
func main() {
wg := sync.WaitGroup{}
for i := 0; i < 20; i++ {
wg.Add(1)
go func(n int) {
key := strconv.Itoa(n)
m.Store(key, n)
value, _ := m.Load(key)
fmt.Printf("k=:%v,v:=%v\n", key, value)
wg.Done()
}(i)
}
wg.Wait()
}
代碼中的加鎖操作因為涉及內核態的背景關系切換會比較耗時、代價比較高,針對基本資料型別我們還可以使用原子操作來保證并發安全,因為原子操作是Go語言提供的方法它在用戶態就可以完成,因此性能比加鎖操作更好,Go語言中原子操作由內置的標準庫sync/atomic提供,
// 原子操作版加函式
func atomicAdd() {
atomic.AddInt64(&x, 1)
wg.Done()
}
make只用于slice、map以及channel的初始化,回傳的還是這三個參考型別本身
變數之間使用參考地址直接可以改變
package main
func swap(a, b *int) {
var temp int
temp = *a
*a = *b
*b = temp
}
func main() {
var a, b = 1, 2
swap(&a, &b)
fmt.Println(a)
fmt.Println(b)
}
//指標小案例
var a int
fmt.Println(&a)
var p *int
p = &a
*p = 20
fmt.Println(a)
在引數賦值時可以不用用一個一個的賦值,可以直接傳遞一個陣列或者切片,特別注意的是在引數后加上“…”即可
package main
import (
"fmt"
)
func test(s string, n ...int) string {
var x int
for _, i := range n {
x += i
}
return fmt.Sprintf(s, x)
}
func main() {
s := []int{1, 2, 3}
res := test("sum: %d", s...) // slice... 展開slice
println(res)
}
"_"識別符號,用來忽略函式的某個回傳值
沒有引數的 return 陳述句回傳各個回傳變數的當前值,這種用法被稱作“裸”回傳,
func add(a, b int) (c int) {
c = a + b
return
}
func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a + b) / 2
return
}
func main() {
var a, b int = 1, 2
c := add(a, b)
sum, avg := calc(a, b)
fmt.Println(a, b, c, sum, avg)
}
命名回傳引數允許 defer 延遲呼叫通過閉包讀取和修改,
defer 是先進后出
package main
func add(x, y int) (z int) {
defer func() {
z += 100
}()
z = x + y
return
}
func main() {
println(add(1, 2))
}
定義一維陣列
var a [5]int = [5]int{1,2,5,6,7}
var a = [...]int{1,2,3,5,6}
d := [...]struct {
name string
age uint8
}{
{"user1", 10}, // 可省略元素型別,
{"user2", 20}, // 別忘了最后一行的逗號,
}
定義二維陣列 第 2 緯度不能用 "..."
var b [3][2]int = [3][2]int{{1,2},{3,4},{5,6}}
var arr1 [2][3]int = [...][3]int{{1, 2, 3}, {7, 8, 9}}
定義slice
全域:
var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
var slice0 []int = arr[start:end]
var slice1 []int = arr[:end]
var slice2 []int = arr[start:]
var slice3 []int = arr[:]
var slice4 = arr[:len(arr)-1] //去掉切片的最后一個元素
區域:
arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
slice5 := arr[start:end]
slice6 := arr[:end]
slice7 := arr[start:]
slice8 := arr[:]
slice9 := arr[:len(arr)-1] //去掉切片的最后一個元素
//通過make來創建切片
var slice []type = make([]type, len)
slice := make([]type, len)
slice := make([]type, len, cap)
定義map
scoreMap := make(map[string]int)
scoreMap["張三"] = 90
scoreMap["小明"] = 100
// 如果key存在ok為true,v為對應的值;不存在ok為false,v為值型別的零值
v, ok := scoreMap["張三"]
if ok {
fmt.Println(v)
} else {
fmt.Println("查無此人")
}
//使用delete()函式洗掉鍵值對
delete(scoreMap, "小明")//將小明:100從map中洗掉
陣列按照下標排序輸出
tetcc := make(map[int]string,5)
tetcc[1] = "smallsha"
tetcc[5] = "smallsha1"
tetcc[3] = "smallsha2"
sli := []int{}
for i := range tetcc {
sli = append(sli,i)
}
sort.Ints(sli)
for i := 0; i < len(tetcc); i++ {
fmt.Println("內容",tetcc[sli[i]])
}
fmt.Printf("%#v\n", sli)
return
if判斷
if test2 :=19; test2> 20 {
fmt.Println("test11212121212")
}else if test2 < 20 {
fmt.Println("test1111")
}
switch使用
test3 := 80
switch test3 {
case 80:
fmt.Println("1")
fallthrough //可以使用fallthrough強制執行后面的case代碼,
case 90:
fmt.Println("2")
case 100:
fmt.Println("3")
default:
fmt.Println("default")
}
多個引數呼叫
func test(s string, n ...int) string {
var x int
for _, i := range n {
x += i
}
return fmt.Sprintf(s, x)
}
s := []int{1, 2, 3}
res := test("sum: %d", s...) // slice... 展開slice
println(res)
閉包使用
func a() func() int {
i := 0
b := func() int{
i++
fmt.Println(i)
return i
}
return b
}
ccccc := a()
ccccc()
ccccc()
return
關鍵字 defer 用于注冊延遲呼叫,
這些呼叫直到 return 前才被執,因此,可以用來做資源清理,
多個defer陳述句,按先進后出的方式執行
慣例是:導致關鍵流程出現不可修復性錯誤的使用 panic,其他使用 error,
func main() {
test()
}
func test() {
defer func() {
if err := recover(); err != nil {
println(err.(string)) // 將 interface{} 轉型為具體型別,
}
}()
panic("panic error!")
}
運算式
package main
import "fmt"
type User struct {
id int
name string
}
func (self *User) Test() {
fmt.Printf("%p, %v\n", self, self)
}
func main() {
u := User{1, "Tom"}
u.Test()
mValue := u.Test
mValue() // 隱式傳遞 receiver
mExpression := (*User).Test
mExpression(&u) // 顯式傳遞 receiver
}
定義error
http://www.topgoer.com/方法/自定義error.html
//回傳例外
package main
import (
"errors"
"fmt"
)
func getCircleArea(radius float32) (area float32, err error) {
if radius < 0 {
// 構建個例外物件
err = errors.New("半徑不能為負")
return
}
area = 3.14 * radius * radius
return
}
func main() {
area, err := getCircleArea(-5)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(area)
}
}
//系統拋例外
package main
import "fmt"
func test01() {
a := [5]int{0, 1, 2, 3, 4}
a[1] = 123
fmt.Println(a)
//a[10] = 11
index := 10
a[index] = 10
fmt.Println(a)
}
func getCircleArea(radius float32) (area float32) {
if radius < 0 {
// 自己拋
panic("半徑不能為負")
}
return 3.14 * radius * radius
}
func test02() {
getCircleArea(-5)
}
//
func test03() {
// 延時執行匿名函式
// 延時到何時?(1)程式正常結束 (2)發生例外時
defer func() {
// recover() 復活 恢復
// 會回傳程式為什么掛了
if err := recover(); err != nil {
fmt.Println(err)
}
}()
getCircleArea(-5)
fmt.Println("這里有沒有執行")
}
func test04() {
test03()
fmt.Println("test04")
}
func main() {
test04()
}
//自定義error
package main
import (
"fmt"
"os"
"time"
)
type PathError struct {
path string
op string
createTime string
message string
}
func (p *PathError) Error() string {
return fmt.Sprintf("path=%s \nop=%s \ncreateTime=%s \nmessage=%s", p.path,
p.op, p.createTime, p.message)
}
func Open(filename string) error {
file, err := os.Open(filename)
if err != nil {
return &PathError{
path: filename,
op: "read",
message: err.Error(),
createTime: fmt.Sprintf("%v", time.Now()),
}
}
defer file.Close()
return nil
}
func main() {
err := Open("/Users/5lmh/Desktop/go/src/test.txt")
switch v := err.(type) {
case *PathError:
fmt.Println("get path error,", v)
default:
}
}
interface 應用
// 空介面作為函式引數
func show(a interface{}) {
fmt.Printf("type:%T value:%v\n", a, a)
}
// 空介面作為map值
var studentInfo = make(map[string]interface{})
studentInfo["name"] = "李白"
studentInfo["age"] = 18
studentInfo["married"] = false
fmt.Println(studentInfo)
go調度 sync.WaitGroup
var wg sync.WaitGroup
func hello(i int) {
defer wg.Done() // goroutine結束就登記-1
fmt.Println("Hello Goroutine!", i)
}
func main() {
for i := 0; i < 10; i++ {
wg.Add(1) // 啟動一個goroutine就登記+1
go hello(i)
}
wg.Wait() // 等待所有登記的goroutine都結束
}
go runtime.Gosched()
//讓出CPU時間片,重新等待安排任務(大概意思就是本來計劃的好好的周末出去燒烤,但是你媽讓你去相親,兩種情況第一就是你相親速度非常快,見面就黃不耽誤你繼續燒烤,第二種情況就是你相親速度特別慢,見面就是你儂我儂的,耽誤了燒烤,但是還饞就是耽誤了燒烤你還得去燒烤)
package main
import (
"fmt"
"runtime"
)
func main() {
go func(s string) {
for i := 0; i < 2; i++ {
fmt.Println(s)
}
}("world")
// 主協程
for i := 0; i < 2; i++ {
// 切一下,再次分配任務
runtime.Gosched()
fmt.Println("hello")
}
}
runtime.Goexit()
//退出當前協程(一邊燒烤一邊相親,突然發現相親物件太丑影響燒烤,果斷讓她滾蛋,然后也就沒有然后了)
package main
import (
"fmt"
"runtime"
)
func main() {
go func() {
defer fmt.Println("A.defer")
func() {
defer fmt.Println("B.defer")
// 結束協程
runtime.Goexit()
defer fmt.Println("C.defer")
fmt.Println("B")
}()
fmt.Println("A")
}()
for {
}
}
runtime.GOMAXPROCS
//Go1.5版本之后,默認使用全部的CPU邏輯核心數
///兩個任務只有一個邏輯核心,此時是做完一個任務再做另一個任務, 將邏輯核心數設為2,此時兩個任務并行執行,代碼如下,
func a() {
for i := 1; i < 10; i++ {
fmt.Println("A:", i)
}
}
func b() {
for i := 1; i < 10; i++ {
fmt.Println("B:", i)
}
}
func main() {
runtime.GOMAXPROCS(2)
go a()
go b()
time.Sleep(time.Second)
}
通道
1.對一個關閉的通道再發送值就會導致panic,
2.對一個關閉的通道進行接識訓一直獲取值直到通道為空,
3.對一個關閉的并且沒有值的通道執行接收操作會得到對應型別的零值,
4.關閉一個已經關閉的通道會導致panic,
5.chan<- int是一個只能發送的通道,可以發送但是不能接收;
6 <-chan int是一個只能接收的通道,可以接收但是不能發送,
func counter(out chan<- int) {
for i := 0; i < 100; i++ {
out <- i
}
close(out)
}
func squarer(out chan<- int, in <-chan int) {
for i := range in {
out <- i * i
}
close(out)
}
func printer(in <-chan int) {
for i := range in {
fmt.Println(i)
}
}
func main() {
ch1 := make(chan int)
ch2 := make(chan int)
go counter(ch1)
go squarer(ch2, ch1)
printer(ch2)
}
通道使用案例
type Job struct {
Id int
RandNum int
}
type Result struct {
job *Job
sum int
}
func createPool(num int, jobChan chan *Job,resultChan chan *Result) {
for i := 0; i < num; i++ {
go func(jobChan chan *Job,resultChan chan *Result) {
for i2 := range jobChan {
r_num := i2.RandNum
var sum int
for r_num !=0 {
tmp := r_num % 10
sum += tmp
r_num /= 10
}
r := &Result{
job: i2,
sum: sum,
}
resultChan <- r
}
}(jobChan,resultChan)
}
}
func main() {
flag.Parse()
jobChan := make(chan *Job, 128)
resultChan := make(chan *Result, 128)
createPool(64, jobChan, resultChan)
// 4.開個列印的協程
go func(resultChan chan *Result) {
// 遍歷結果管道列印
for result := range resultChan {
fmt.Printf("job id:%v randnum:%v result:%d\n", result.job.Id,
result.job.RandNum, result.sum)
}
}(resultChan)
var id int
// 回圈創建job,輸入到管道
for {
id++
// 生成亂數
r_num := rand.Int()
job := &Job{
Id: id,
RandNum: r_num,
}
jobChan <- job
}
return
}
select 監聽通道
select {
case <-chan1:
// 如果chan1成功讀到資料,則進行該case處理陳述句
case chan2 <- 1:
// 如果成功向chan2寫入資料,則進行該case處理陳述句
default:
// 如果上面都沒有成功,則進入default處理流程
}
flag使用 和 os.args
var name string
var age int
var married bool
var delay time.Duration
flag.StringVar(&name, "name", "張三", "姓名")
flag.IntVar(&age, "age", 18, "年齡")
flag.BoolVar(&married, "married", false, "婚否")
flag.DurationVar(&delay, "d", 0, "延遲的時間間隔")
或者使用
name := flag.String("name", "張三", "姓名")
age := flag.Int("age", 18, "年齡")
married := flag.Bool("married", false, "婚否")
delay := flag.Duration("d", 0, "時間間隔")
//決議命令列引數
flag.Parse()
fmt.Println(name, age, married, delay)
//回傳命令列引數后的其他引數
fmt.Println(flag.Args())
//回傳命令列引數后的其他引數個數
fmt.Println(flag.NArg())
//回傳使用的命令列引數個數
fmt.Println(flag.NFlag())
//os.args
if len(os.Args) > 0 {
for index, arg := range os.Args {
fmt.Printf("args[%d]=%v\n", index, arg)
}
}
Log檔案
logFile, err := os.OpenFile("./smallsha.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println("open log file failed, err:", err)
return
}
log.SetOutput(logFile) //設定日志檔案寫入
log.SetFlags(log.Llongfile | log.Lmicroseconds | log.Ldate)
log.SetPrefix("[smallsha]")
log.Printf("%s","smallsha")
log.Println("test")
//log.Panic("test1")
//log.Fatalln("test2")
logger := log.New(os.Stdout, "<New>", log.Lshortfile|log.Ldate|log.Ltime)
logger.Println("這是自定義的logger記錄的日志,")
回圈操作
arr := [5]int{1,2,4,5,6,8}
for i,num :=range arr {
fmt.Println(i,num)
}
//while for 回圈配合通道
var (
ch11 = make(chan int)
ch12 = make(chan int)
)
go func() {
for i := 0; i < 10; i++ {
ch11 <- i
}
close(ch11)
}()
go func() {
for {
i, ok := <-ch11
if !ok {
break
}
ch12 <- i * i
}
close(ch12)
}()
for i := range ch12 {
fmt.Println(i)
}
指標
const MAX int =3
func main(){
a :=[]int{1,3,5}
var ptr [MAX]*int;
for i = 0; i < MAX; i++ {
ptr[i] = &a[i] /* 整數地址賦值給指標陣列 */
}
for i = 0; i < MAX; i++ {
fmt.Printf("a[%d] = %d\n", i,*ptr[i] )
}
}
strconv 使用
s3, _ := strconv.ParseBool("1")
fmt.Printf("%# v\n", pretty.Formatter(s3))
return
//int 轉 string
s2 := 100
i2 := strconv.Itoa(s2)
fmt.Printf("%# v\n", pretty.Formatter(i2))
return
//string 轉 int
s1 := "100"
i1, err := strconv.Atoi(s1)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%# v\n", pretty.Formatter(i1))
return
template使用可以注冊http
package logic
import (
"fmt"
"html/template"
"net/http"
)
func init() {
http.HandleFunc("/",sayHello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Println(err)
return
}
}
type UserInfo struct {
Name string
Gender string
Age int
}
func sayHello(w http.ResponseWriter,r *http.Request) {
// 決議指定檔案生成模板物件
tmpl, err := template.ParseFiles("./hello.html")
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
// 利用給定資料渲染模板,并將結果寫入w
user := UserInfo{
Name: "枯藤",
Gender: "男",
Age: 18,
}
// 利用給定資料渲染模板,并將結果寫入w
tmpl.Execute(w, user)
}
定義結構體
package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
var Book1 Books /* 宣告 Book1 為 Books 型別 */
var Book2 Books /* 宣告 Book2 為 Books 型別 */
/* book 1 描述 */
Book1.title = "Go 語言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 語言教程"
Book1.book_id = 6495407
/* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 語言教程"
Book2.book_id = 6495700
/* 列印 Book1 資訊 */
printBook(&Book1)
/* 列印 Book2 資訊 */
printBook(&Book2)
}
func printBook( book *Books ) {
fmt.Printf( "Book title : %s\n", book.title)
fmt.Printf( "Book author : %s\n", book.author)
fmt.Printf( "Book subject : %s\n", book.subject)
fmt.Printf( "Book book_id : %d\n", book.book_id)
}
//結構體new 和賦值
type Person struct {
Username string `json:"username"`
Password string `json:"password"`
}
//宣告構造方法
func newPerson(username string, password string) *Person {
return &Person{
Username: username,
Password: password,
}
}
//定義修改結構體的方法
func (p *Person) setUsername(username string) {
p.Username = username
}
map操作
package main
import "fmt"
func main() {
var countryCapitalMap map[string]string /*創建集合 */
countryCapitalMap = make(map[string]string)
/* map插入key - value對,各個國家對應的首都 */
countryCapitalMap [ "France" ] = "巴黎"
countryCapitalMap [ "Italy" ] = "羅馬"
countryCapitalMap [ "Japan" ] = "東京"
countryCapitalMap [ "India " ] = "新德里"
/*使用鍵輸出地圖值 */
for country := range countryCapitalMap {
fmt.Println(country, "首都是", countryCapitalMap [country])
}
/*查看元素在集合中是否存在 */
capital, ok := countryCapitalMap [ "American" ]
/*洗掉元素*/ delete(countryCapitalMap, "France")
/*如果確定是真實的,則存在,否則不存在 */
/*fmt.Println(capital) */
/*fmt.Println(ok) */
if (ok) {
fmt.Println("American 的首都是", capital)
} else {
fmt.Println("American 的首都不存在")
}
}
宣告變數
package main
import "fmt"
func main() {
var a string = "Runoob"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
宣告方法
package main
import "fmt"
func swap(x, y string) (string, string) {
return y, x
}
func main() {
a, b := swap("Google", "Runoob")
fmt.Println(a, b)
}
定義陣列
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
package main
import "fmt"
func main() {
var n [10]int /* n 是一個長度為 10 的陣列 */
var i,j int
/* 為陣列 n 初始化元素 */
for i = 0; i < 10; i++ {
n[i] = i + 100 /* 設定元素為 i + 100 */
}
/* 輸出每個陣列元素的值 */
for j = 0; j < 10; j++ {
fmt.Printf("Element[%d] = %d\n", j, n[j] )
}
}
Go 語言結構體
package main
import "fmt"
type Books struct {
title string
author string
subject string
book_id int
}
func main() {
var Book1 Books /* 宣告 Book1 為 Books 型別 */
var Book2 Books /* 宣告 Book2 為 Books 型別 */
/* book 1 描述 */
Book1.title = "Go 語言"
Book1.author = "www.runoob.com"
Book1.subject = "Go 語言教程"
Book1.book_id = 6495407
/* book 2 描述 */
Book2.title = "Python 教程"
Book2.author = "www.runoob.com"
Book2.subject = "Python 語言教程"
Book2.book_id = 6495700
/* 列印 Book1 資訊 */
fmt.Printf( "Book 1 title : %s\n", Book1.title)
fmt.Printf( "Book 1 author : %s\n", Book1.author)
fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)
/* 列印 Book2 資訊 */
fmt.Printf( "Book 2 title : %s\n", Book2.title)
fmt.Printf( "Book 2 author : %s\n", Book2.author)
fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
}
結構體作為函式引數
func printBook( book Books ) {
fmt.Printf( "Book title : %s\n", book.title)
fmt.Printf( "Book author : %s\n", book.author)
fmt.Printf( "Book subject : %s\n", book.subject)
fmt.Printf( "Book book_id : %d\n", book.book_id)
}
宣告函式和方法區別
#函式
func main() {
sum := add(1, 2)
fmt.Println(sum)
}
func add(a, b int) int {
return a + b
}
#方法
type person struct {
name string
}
func (p person) String() string{
return "the person name is "+p.name
}
func main() {
p:=person{name:"張三"}
fmt.Println(p.String())
}
#可變引數
func main() {
print("1","2","3")
}
func print (a ...interface{}){
for _,v:=range a{
fmt.Print(v)
}
fmt.Println()
}
修改字串 需要先轉換成 byte 或者 rune
func changeString() {
s1 := "hello"
// 強制型別轉換
byteS1 := []byte(s1)
byteS1[0] = 'H'
fmt.Println(string(byteS1))
s2 := "博客"
runeS2 := []rune(s2)
runeS2[0] = '狗'
fmt.Println(string(runeS2))
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/285572.html
標籤:PHP
上一篇:GO反射類實體
下一篇:WordPress二次開發難嗎?
