GOTIPS

/*

gotips_test.go:

? Golang速學速查速用代碼手冊

Source: github.com/coderzh/CodeTips/blob/master/gotips_test.go

Author: coderzh(github.com/coderzh)

Blog: http://blog.coderzh.com

參考:《Go語言編程》

*/

package main

import (

"errors"

"fmt"

"github.com/stretchr/testify/assert"

"io"

"io/ioutil"

"log"

"math"

"os"

"path/filepath"

"regexp"

"strings"

"sync"

"testing"

"time"

)

// 0. 注釋

/*

規(guī)范:

1. 命名:駱駝命名法(不要用下劃線)

命令:

go get github.com/coderzh/xxx

go build calc

go run xxx.go

go install calc

*/

// 1. Hello World

func helloWorld() {

fmt.Println("Hello, 世界")

}

// 2.變量類型

func typeDemo() {

// 變量聲明

var v1 int

var (

v2 int

v3 string

)

//var p *int // 指針類型

// 變量初始化

var v4 int = 10

// 等價于:

var v5 = 10

// 一般這樣就好

v6 := 10

// 賦值饵筑,多重賦值

v1 = 10

v2, v3 = 20, "test"

// 匿名變量 _

_, v4 = v5, v6

fmt.Println(v1, v2, v3, v4)

// 常量

const Pi float64 = 3.1415926

const MaxPlayer = 10

// 枚舉

const (

Sunday = iota // iota從0遞增

Mondy

Tuesday

// ...

)

// 類型

// 1. 布爾

var b1 bool

b1 = true

b1 = (1 == 2)

fmt.Println(b1)

// 2. 整形

// int8 uint8 int16 uint16 int32 uint32 int64 uint64 int uint uintptr

var i32 int32

// 強制轉換

i32 = int32(64)

// 運算:+, -, *, /, %(求余)

// 比較:>, <, ==, >=, <=, !=

// 位運算:x << y, x >> y, x ^ y, x & y, x | y, ^x (取反)

fmt.Println(i32)

// 3. 浮點

// float32, float64

var f1 float64 = 1.0001

var f2 float64 = 1.0002

// 浮點比較

isEqual := math.Dim(f1, f2) < 0.0001

fmt.Println(isEqual)

// 4. 字符串

var s1 string

s1 = "abc"

// 字符串連接

s1 = s1 + "ddd"

// 取長度

n := len(s1)

// 取字符

c1 := s1[0]

// 反引號蜕青,不轉義十厢,常用于正則表達式

s1 = `\w+`

fmt.Println(c1)

fmt.Println(strings.HasPrefix("prefix", "pre")) // true

fmt.Println(strings.HasSuffix("suffix", "fix")) // true

// 字節(jié)遍歷

for i := 0; i < n; i++ {

ch := s1[i]

fmt.Println(ch)

}

// Unicode字符Rune遍歷

for i, ch := range s1 {

fmt.Println(i, ch)

}

// 5. 數(shù)組

var arr1 [32]int

//var arr2 [3][8]int // 二維數(shù)組

// 初始化

arr1 = [32]int{0}

array := [5]int{1, 2, 3, 4, 5}

// 臨時結構體數(shù)組

structArray := []struct {

name string

age? int

}{{"Tim", 18}, {"Jim", 20}}

// 數(shù)組遍歷

for i := 0; i < len(array); i++ {

fmt.Println(array[i])

}

for i, v := range structArray {

fmt.Println(i, v)

}

// 數(shù)組是值類型,每次參數(shù)傳遞都是一份拷貝

// 數(shù)組切片Slice

var mySlice []int = arr1[:2]

mySlice1 := make([]int, 5)

mySlice2 := make([]int, 5, 10)

fmt.Println("len(mySlice2:", len(mySlice2)) // 5

fmt.Println("cap(mySlice2:", cap(mySlice2)) // 10

mySlice3 := append(mySlice, 2, 3, 4)

mySlice4 := append(mySlice, mySlice1...)

copy(mySlice3, mySlice4)

// 6. Map

var m map[int]string

m[1] = "ddd"

m1 := make(map[int]string)

m2 := map[int]string{

1: "a",

2: "b",

}

delete(m2, 1)

value, ok := m1[1]

if ok {

fmt.Println(value)

}

for k, v := range m2 {

fmt.Println(k, v)

}

}

// 3. 流程控制

func flowDemo() {

// if else

a := 10

if a < 10 {

// ..

} else {

// ..

}

// switch

switch a {

case 0:

fmt.Println("0")

case 10:

fmt.Println("10")

default:

fmt.Println("default")

}

switch {

case a < 10:

fmt.Println("<10")

case a < 20:

fmt.Println("<20")

}

// 循環(huán)

for i := 0; i < 10; i++ {

}

// 無限循環(huán)

sum := 0

for {

sum++

if sum > 10 {

break

// 指定break

// break JLoop

}

}

goto JLoop

JLoop:

// break to here

}

// 4. 函數(shù)

// func 函數(shù)名(參數(shù)列表)(返回值列表) {

// }

func sum1(value1 int, value2 int) (result int, err error) {

// err = errors.New("xxxx")

return value1 + value2, nil

}

func sum2(value1, value2 int) int {

return value1 + value2

}

// 不定參數(shù)

// myFunc(1, 2, 3, 4, 5)

func myFunc(args ...int) {

for _, arg := range args {

fmt.Println(arg)

}

// 傳遞

// myFunc2(args...)

// myFunc2(args[1:]...)

}

// 任意類型的不定參數(shù)

func myPrintf(args ...interface{}) {

for _, arg := range args {

switch arg.(type) {

case int:

fmt.Println(arg, "is int")

case string:

fmt.Println(arg, "is string")

default:

fmt.Println(arg, "is unknown")

}

}

}

// 匿名函數(shù)

func anonymousFunc() {

f := func(a, b int) int {

return a + b

}

f(1, 2)

}

// defer

func deferDemo(path string) {

f, err := os.Open(path)

if err != nil {

return

}

defer f.Close()

// or

defer func() {

if r := recover(); r != nil {

fmt.Printf("Runtime error caught: %v", r)

}

}()

}

// 5. 結構體

type Rect struct {

// 小寫為private

x, y float64

// 大寫為public

Width, Height float64

}

// 大寫方法為public爷耀,小寫為private

func (r *Rect) Area() float64 {

return r.Width * r.Height

}

func netRect(x, y, width, height float64) *Rect {

// 實例化結構體

// rect1 := new(Rect)

// rect2 := &Rect{}

// rect3 := &Rect{Width:100, Height:200}

return &Rect{x, y, width, height}

}

// 匿名組合

type Base struct {

Name string

}

func (base *Base) Foo() {}

func (base *Base) Bar() {}

type Foo struct {

Base

*log.Logger

}

func (foo *Foo) Bar() {

foo.Base.Bar()

// ...

}

// 非侵入式接口

type IFile interface {

Read(buf []byte) (n int, err error)

Write(buf []byte) (n int, err error)

}

type File struct {

}

func (file *File) Read(buf []byte) (n int, err error) {

return 0, nil

}

func (file *File) Write(buf []byte) (n int, err error) {

return 0, nil

}

func interfaceDemo() {

// 只要實現(xiàn)了Read, Write方法即可

var file IFile = new(File)

// 接口查詢

// 是否實現(xiàn)了IFile接口

if file2, ok := file.(IFile); ok {

file2.Read([]byte{})

}

// 實例類型是否是File

if file3, ok := file.(*File); ok {

file3.Read([]byte{})

}

// 類型查詢

switch v := file.(type) {

}

}

// 6. 并發(fā)編程

func counting(ch chan int) {

ch <- 1

fmt.Println("counting")

}

func channelDemo() {

chs := make([]chan int, 10)

for i := 0; i < len(chs); i++ {

chs[i] = make(chan int)

// 帶緩沖區(qū)大小

// c: = make(chan int, 1024)

// for i:= range c {

// }

go counting(chs[i])

}

for _, ch := range chs {

<-ch

// channel select

/*

select {

case <-ch:

// ...

case ch <- 1:

}

*/

}

// 單向Channel

var ch1 chan<- int // 只能寫入int

var ch2 <-chan int // 只能讀出int

// 關閉Channel

close(ch1)

_, ok := <-ch2

if !ok {

// already closed

}

}

// 鎖

var m sync.Mutex

func lockDemo() {

m.Lock()

// do something

defer m.Unlock()

}

// 全局唯一操作

var once sync.Once

// once.Do(someFunction)

// 7. 網(wǎng)絡編程

// import "net"

// net.Dial("tcp", "127.0.0.1:8080")

// 8. json處理

// import "encoding/json"

// json.Marshal(obj) 序列化

// json.Unmarshal() 反序列化

// 9. Web開發(fā)

// import "net/http"

// 模板

// import "html/template"

// 10. 常用庫

// import "os"

// import "io"

// import "flag"

// import "strconv"

// import "crypto/sha1"

// import "crypto/md5"

// 11. 單元測試

// _test結尾的go文件: xxx_test.go

// 函數(shù)名以Test開頭

func TestDemo(t *testing.T) {

r := sum2(2, 3)

if r != 5 {

t.Errorf("sum2(2, 3) failed. Got %d, expect 5.", r)

}

assert.Equal(t, 1, 1)

}

// 12. 性能測試

func benchmarkAdd(b *testing.B) {

b.StopTimer()

// dosometing

b.StartTimer()

}

/*

其他常用的代碼片段

*/

// 1. 遍歷文件 filepath.Walk

// import "path/filepath"

func doHashWalk(dirPath string) error {

fullPath, err := filepath.Abs(dirPath)

if err != nil {

return err

}

callback := func(path string, fi os.FileInfo, err error) error {

return hashFile(fullPath, path, fi, err)

}

return filepath.Walk(fullPath, callback)

}

func hashFile(root string, path string, fi os.FileInfo, err error) error {

if fi.IsDir() {

return nil

}

rel, err := filepath.Rel(root, path)

if err != nil {

return err

}

log.Println("hash rel:", rel, "abs:", path)

return nil

}

// 2. 讀取文件

// import "io/ioutil"

func readFileDemo(filename string) {

content, err := ioutil.ReadFile(filename)

if err != nil {

//Do something

}

lines := strings.Split(string(content), "\n")

fmt.Println("line count:", len(lines))

}

// 判斷目錄或文件是否存在

func existsPathCheck(path string) (bool, error) {

// 判斷不存在

if _, err := os.Stat(path); os.IsNotExist(err) {

// 不存在

}

// 判斷是否存在

_, err := os.Stat(path)

if err == nil {

return true, nil

}

if os.IsNotExist(err) {

return false, nil

}

return true, err

}

// 文件目錄操作

func fileDirDemo() {

// 級聯(lián)創(chuàng)建目錄

os.MkdirAll("/path/to/create", 0777)

}

// 拷貝文件

func copyFile(source string, dest string) (err error) {

sf, err := os.Open(source)

if err != nil {

return err

}

defer sf.Close()

df, err := os.Create(dest)

if err != nil {

return err

}

defer df.Close()

_, err = io.Copy(df, sf)

if err == nil {

si, err := os.Stat(source)

if err != nil {

err = os.Chmod(dest, si.Mode())

}

}

return

}

// 拷貝目錄

func copyDir(source string, dest string) (err error) {

fi, err := os.Stat(source)

if err != nil {

return err

}

if !fi.IsDir() {

return errors.New(source + " is not a directory")

}

err = os.MkdirAll(dest, fi.Mode())

if err != nil {

return err

}

entries, err := ioutil.ReadDir(source)

for _, entry := range entries {

sfp := filepath.Join(source, entry.Name())

dfp := filepath.Join(dest, entry.Name())

if entry.IsDir() {

err = copyDir(sfp, dfp)

if err != nil {

fmt.Println(err)

}

} else {

err = copyFile(sfp, dfp)

if err != nil {

fmt.Println(err)

}

}

}

return nil

}

// 3. 時間處理

// import "time"

func TestTimeDemo(t *testing.T) {

// Parse

postDate, err := time.Parse("2006-01-02 15:04:05", "2015-09-30 19:19:00")

fmt.Println(postDate, err)

// Format

assert.Equal(t, "2015/Sep/30 07:19:00", postDate.Format("2006/Jan/02 03:04:05"))

assert.Equal(t, "2015-09-30T19:19:00Z", postDate.Format(time.RFC3339))

}

// 4. 正則表達式

// import "regexp"

func TestRegexp(t *testing.T) {

// 查找匹配

re := regexp.MustCompile(`(\d+)-(\d+)`)

r := re.FindAllStringSubmatch("123-666", -1)

assert.Equal(t, 1, len(r))

assert.Equal(t, "123", r[0][1])

assert.Equal(t, "666", r[0][2])

cjkRe := regexp.MustCompile(`\p{Han}|\p{Hangul}|\p{Hiragana}|\p{Katakana}`)

assert.True(t, cjkRe.MatchString("中文"))

assert.True(t, cjkRe.MatchString("???"))

assert.True(t, cjkRe.MatchString("カテゴリー"))

assert.False(t, cjkRe.MatchString("abc"))

}

func main() {

helloWorld()

}

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市拍皮,隨后出現(xiàn)的幾起案子歹叮,更是在濱河造成了極大的恐慌,老刑警劉巖铆帽,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咆耿,死亡現(xiàn)場離奇詭異,居然都是意外死亡爹橱,警方通過查閱死者的電腦和手機票灰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宅荤,“玉大人屑迂,你說我怎么就攤上這事》爰” “怎么了惹盼?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惫确。 經(jīng)常有香客問我手报,道長蚯舱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任掩蛤,我火速辦了婚禮枉昏,結果婚禮上,老公的妹妹穿的比我還像新娘揍鸟。我一直安慰自己兄裂,他們只是感情好,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布阳藻。 她就那樣靜靜地躺著晰奖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腥泥。 梳的紋絲不亂的頭發(fā)上匾南,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音蛔外,去河邊找鬼蛆楞。 笑死,一個胖子當著我的面吹牛夹厌,可吹牛的內(nèi)容都是我干的臊岸。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼尊流,長吁一口氣:“原來是場噩夢啊……” “哼帅戒!你這毒婦竟也來了?” 一聲冷哼從身側響起崖技,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤逻住,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后迎献,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞎访,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年吁恍,在試婚紗的時候發(fā)現(xiàn)自己被綠了扒秸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡冀瓦,死狀恐怖伴奥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翼闽,我是刑警寧澤拾徙,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站感局,受9級特大地震影響尼啡,放射性物質(zhì)發(fā)生泄漏暂衡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一崖瞭、第九天 我趴在偏房一處隱蔽的房頂上張望狂巢。 院中可真熱鬧,春花似錦书聚、人聲如沸唧领。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疹吃。三九已至蹦疑,卻和暖如春西雀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背歉摧。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工艇肴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叁温。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓再悼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親膝但。 傳聞我的和親對象是個殘疾皇子冲九,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容