Golang 急速入门手册

  1 /*
  2 gotips_test.go:
  3 Golang速学速查速用代码手册
  4 
  5 Source: github.com/coderzh/CodeTips/blob/master/gotips_test.go
  6 
  7 Author: coderzh(github.com/coderzh)
  8 Blog: http://blog.coderzh.com
  9 参考:《Go语言编程》
 10 */
 11 
 12 package main
 13 
 14 import (
 15 "errors"
 16 "fmt"
 17 "github.com/stretchr/testify/assert"
 18 "io"
 19 "io/ioutil"
 20 "log"
 21 "math"
 22 "os"
 23 "path/filepath"
 24 "regexp"
 25 "strings"
 26 "sync"
 27 "testing"
 28 "time"
 29 )
 30 
 31 // 0. 注释
 32 /*
 33 规范:
 34 1. 命名:骆驼命名法(不要用下划线)
 35 
 36 命令:
 37 go get github.com/coderzh/xxx
 38 go build calc
 39 go run xxx.go
 40 go install calc
 41 */
 42 
 43 // 1. Hello World
 44 func helloWorld() {
 45 fmt.Println("Hello, 世界")
 46 }
 47 
 48 // 2.变量类型
 49 func typeDemo() {
 50 // 变量声明
 51 var v1 int
 52 var (
 53 v2 int
 54 v3 string
 55 )
 56 //var p *int // 指针类型
 57 
 58 // 变量初始化
 59 var v4 int = 10
 60 // 等价于:
 61 var v5 = 10
 62 // 一般这样就好
 63 v6 := 10
 64 
 65 // 赋值,多重赋值
 66 v1 = 10
 67 v2, v3 = 20, "test"
 68 // 匿名变量 _
 69 _, v4 = v5, v6
 70 
 71 fmt.Println(v1, v2, v3, v4)
 72 
 73 // 常量
 74 const Pi float64 = 3.1415926
 75 const MaxPlayer = 10
 76 
 77 // 枚举
 78 const (
 79 Sunday = iota // iota从0递增
 80 Mondy
 81 Tuesday
 82 // ...
 83 )
 84 
 85 // 类型
 86 // 1. 布尔
 87 var b1 bool
 88 b1 = true
 89 b1 = (1 == 2)
 90 
 91 fmt.Println(b1)
 92 
 93 // 2. 整形
 94 // int8 uint8 int16 uint16 int32 uint32 int64 uint64 int uint uintptr
 95 var i32 int32
 96 // 强制转换
 97 i32 = int32(64)
 98 // 运算:+, -, *, /, %(求余)
 99 // 比较:>, <, ==, >=, <=, !=
100 // 位运算:x << y, x >> y, x ^ y, x & y, x | y, ^x (取反)
101 
102 fmt.Println(i32)
103 
104 // 3. 浮点
105 // float32, float64
106 var f1 float64 = 1.0001
107 var f2 float64 = 1.0002
108 // 浮点比较
109 isEqual := math.Dim(f1, f2) < 0.0001
110 
111 fmt.Println(isEqual)
112 
113 // 4. 字符串
114 var s1 string
115 s1 = "abc"
116 // 字符串连接
117 s1 = s1 + "ddd"
118 // 取长度
119 n := len(s1)
120 // 取字符
121 c1 := s1[0]
122 // 反引号,不转义,常用于正则表达式
123 s1 = `\w+`
124 
125 fmt.Println(c1)
126 
127 fmt.Println(strings.HasPrefix("prefix", "pre")) // true
128 fmt.Println(strings.HasSuffix("suffix", "fix")) // true
129 
130 // 字节遍历
131 for i := 0; i < n; i++ {
132 ch := s1[i]
133 fmt.Println(ch)
134 }
135 // Unicode字符遍历
136 for i, ch := range s1 {
137 fmt.Println(i, ch)
138 }
139 
140 // 5. 数组
141 var arr1 [32]int
142 //var arr2 [3][8]int // 二维数组
143 // 初始化
144 arr1 = [32]int{0}
145 array := [5]int{1, 2, 3, 4, 5}
146 // 临时结构体数组
147 structArray := []struct {
148 name string
149 age int
150 }{{"Tim", 18}, {"Jim", 20}}
151 
152 // 数组遍历
153 for i := 0; i < len(array); i++ {
154 fmt.Println(array[i])
155 }
156 for i, v := range structArray {
157 fmt.Println(i, v)
158 }
159 // 数组是值类型,每次参数传递都是一份拷贝
160 
161 // 数组切片Slice
162 var mySlice []int = arr1[:2]
163 mySlice1 := make([]int, 5)
164 mySlice2 := make([]int, 5, 10)
165 
166 fmt.Println("len(mySlice2:", len(mySlice2)) // 5
167 fmt.Println("cap(mySlice2:", cap(mySlice2)) // 10
168 
169 mySlice3 := append(mySlice, 2, 3, 4)
170 mySlice4 := append(mySlice, mySlice1...)
171 
172 copy(mySlice3, mySlice4)
173 
174 // 6. Map
175 var m map[int]string
176 m[1] = "ddd"
177 m1 := make(map[int]string)
178 m2 := map[int]string{
179 1: "a",
180 2: "b",
181 }
182 
183 delete(m2, 1)
184 
185 value, ok := m1[1]
186 if ok {
187 fmt.Println(value)
188 }
189 
190 for k, v := range m2 {
191 fmt.Println(k, v)
192 }
193 
194 }
195 
196 // 3. 流程控制
197 func flowDemo() {
198 // if else
199 a := 10
200 if a < 10 {
201 // ..
202 } else {
203 // ..
204 }
205 
206 // switch
207 switch a {
208 case 0:
209 fmt.Println("0")
210 case 10:
211 fmt.Println("10")
212 default:
213 fmt.Println("default")
214 }
215 
216 switch {
217 case a < 10:
218 fmt.Println("<10")
219 case a < 20:
220 fmt.Println("<20")
221 }
222 
223 // 循环
224 for i := 0; i < 10; i++ {
225 }
226 // 无限循环
227 sum := 0
228 for {
229 sum++
230 if sum > 10 {
231 break
232 // 指定break
233 // break JLoop
234 }
235 }
236 
237 goto JLoop
238 
239 JLoop:
240 // break to here
241 
242 }
243 
244 // 4. 函数
245 // func 函数名(参数列表)(返回值列表) {
246 // }
247 func sum1(value1 int, value2 int) (result int, err error) {
248 // err = errors.New("xxxx")
249 return value1 + value2, nil
250 }
251 
252 func sum2(value1, value2 int) int {
253 return value1 + value2
254 }
255 
256 // 不定参数
257 // myFunc(1, 2, 3, 4, 5)
258 func myFunc(args ...int) {
259 for _, arg := range args {
260 fmt.Println(arg)
261 }
262 // 传递
263 // myFunc2(args...)
264 // myFunc2(args[1:]...)
265 }
266 
267 // 任意类型的不定参数
268 func myPrintf(args ...interface{}) {
269 for _, arg := range args {
270 switch arg.(type) {
271 case int:
272 fmt.Println(arg, "is int")
273 case string:
274 fmt.Println(arg, "is string")
275 default:
276 fmt.Println(arg, "is unknown")
277 }
278 }
279 }
280 
281 // 匿名函数
282 func anonymousFunc() {
283 f := func(a, b int) int {
284 return a + b
285 }
286 
287 f(1, 2)
288 }
289 
290 // defer
291 func deferDemo(path string) {
292 f, err := os.Open(path)
293 if err != nil {
294 return
295 }
296 
297 defer f.Close()
298 // or
299 defer func() {
300 if r := recover(); r != nil {
301 fmt.Printf("Runtime error caught: %v", r)
302 }
303 }()
304 }
305 
306 // 5. 结构体
307 type Rect struct {
308 // 小写为private
309 x, y float64
310 // 大写为public
311 Width, Height float64
312 }
313 
314 // 大写方法为public,小写为private
315 func (r *Rect) Area() float64 {
316 return r.Width * r.Height
317 }
318 
319 func netRect(x, y, width, height float64) *Rect {
320 // 实例化结构体
321 // rect1 := new(Rect)
322 // rect2 := &Rect{}
323 // rect3 := &Rect{Width:100, Height:200}
324 return &Rect{x, y, width, height}
325 }
326 
327 // 匿名组合
328 type Base struct {
329 Name string
330 }
331 
332 func (base *Base) Foo() {}
333 func (base *Base) Bar() {}
334 
335 type Foo struct {
336 Base
337 *log.Logger
338 }
339 
340 func (foo *Foo) Bar() {
341 foo.Base.Bar()
342 // ...
343 }
344 
345 // 非侵入式接口
346 type IFile interface {
347 Read(buf []byte) (n int, err error)
348 Write(buf []byte) (n int, err error)
349 }
350 
351 type File struct {
352 }
353 
354 func (file *File) Read(buf []byte) (n int, err error) {
355 return 0, nil
356 }
357 
358 func (file *File) Write(buf []byte) (n int, err error) {
359 return 0, nil
360 }
361 
362 func interfaceDemo() {
363 // 只要实现了Read, Write方法即可
364 var file IFile = new(File)
365 
366 // 接口查询
367 // 是否实现了IFile接口
368 if file2, ok := file.(IFile); ok {
369 file2.Read([]byte{})
370 }
371 // 实例类型是否是File
372 if file3, ok := file.(*File); ok {
373 file3.Read([]byte{})
374 }
375 
376 // 类型查询
377 switch v := file.(type) {
378 }
379 }
380 
381 // 6. 并发编程
382 func counting(ch chan int) {
383 ch <- 1
384 fmt.Println("counting")
385 }
386 
387 func channelDemo() {
388 chs := make([]chan int, 10)
389 for i := 0; i < len(chs); i++ {
390 chs[i] = make(chan int)
391 // 带缓冲区大小
392 // c: = make(chan int, 1024)
393 // for i:= range c {
394 // }
395 go counting(chs[i])
396 }
397 
398 for _, ch := range chs {
399 <-ch
400 // channel select
401 /*
402 select {
403 case <-ch:
404 // ...
405 case ch <- 1:
406 }
407 */
408 }
409 
410 // 单向Channel
411 var ch1 chan<- int // 只能写入int
412 var ch2 <-chan int // 只能读出int
413 
414 // 关闭Channel
415 close(ch1)
416 _, ok := <-ch2
417 if !ok {
418 // already closed
419 }
420 }
421 
422 //
423 var m sync.Mutex
424 
425 func lockDemo() {
426 m.Lock()
427 // do something
428 defer m.Unlock()
429 }
430 
431 // 全局唯一操作
432 var once sync.Once
433 
434 // once.Do(someFunction)
435 
436 // 7. 网络编程
437 // import "net"
438 // net.Dial("tcp", "127.0.0.1:8080")
439 
440 // 8. json处理
441 // import "encoding/json"
442 // json.Marshal(obj) 序列化
443 // json.Unmarshal() 反序列化
444 
445 // 9. Web开发
446 // import "net/http"
447 // 模板
448 // import "html/template"
449 
450 // 10. 常用库
451 // import "os"
452 // import "io"
453 // import "flag"
454 // import "strconv"
455 // import "crypto/sha1"
456 // import "crypto/md5"
457 
458 // 11. 单元测试
459 // _test结尾的go文件: xxx_test.go
460 // 函数名以Test开头
461 func TestDemo(t *testing.T) {
462 r := sum2(2, 3)
463 if r != 5 {
464 t.Errorf("sum2(2, 3) failed. Got %d, expect 5.", r)
465 }
466 
467 assert.Equal(t, 1, 1)
468 }
469 
470 // 12. 性能测试
471 func benchmarkAdd(b *testing.B) {
472 b.StopTimer()
473 // dosometing
474 b.StartTimer()
475 }
476 
477 /*
478 其他常用的代码片段
479 */
480 
481 // 1. 遍历文件 filepath.Walk
482 // import "path/filepath"
483 func doHashWalk(dirPath string) error {
484 
485 fullPath, err := filepath.Abs(dirPath)
486 
487 if err != nil {
488 return err
489 }
490 
491 callback := func(path string, fi os.FileInfo, err error) error {
492 return hashFile(fullPath, path, fi, err)
493 }
494 
495 return filepath.Walk(fullPath, callback)
496 }
497 
498 func hashFile(root string, path string, fi os.FileInfo, err error) error {
499 if fi.IsDir() {
500 return nil
501 }
502 rel, err := filepath.Rel(root, path)
503 if err != nil {
504 return err
505 }
506 log.Println("hash rel:", rel, "abs:", path)
507 return nil
508 }
509 
510 // 2. 读取文件
511 // import "io/ioutil"
512 func readFileDemo(filename string) {
513 content, err := ioutil.ReadFile(filename)
514 if err != nil {
515 //Do something
516 }
517 lines := strings.Split(string(content), "\n")
518 fmt.Println("line count:", len(lines))
519 }
520 
521 // 判断目录或文件是否存在
522 func existsPathCheck(path string) (bool, error) {
523 // 判断不存在
524 if _, err := os.Stat(path); os.IsNotExist(err) {
525 // 不存在
526 }
527 
528 // 判断是否存在
529 _, err := os.Stat(path)
530 if err == nil {
531 return true, nil
532 }
533 if os.IsNotExist(err) {
534 return false, nil
535 }
536 return true, err
537 }
538 
539 // 文件目录操作
540 func fileDirDemo() {
541 // 级联创建目录
542 os.MkdirAll("/path/to/create", 0777)
543 }
544 
545 // 拷贝文件
546 func copyFile(source string, dest string) (err error) {
547 sf, err := os.Open(source)
548 if err != nil {
549 return err
550 }
551 defer sf.Close()
552 df, err := os.Create(dest)
553 if err != nil {
554 return err
555 }
556 defer df.Close()
557 _, err = io.Copy(df, sf)
558 if err == nil {
559 si, err := os.Stat(source)
560 if err != nil {
561 err = os.Chmod(dest, si.Mode())
562 }
563 
564 }
565 return
566 }
567 
568 // 拷贝目录
569 func copyDir(source string, dest string) (err error) {
570 fi, err := os.Stat(source)
571 if err != nil {
572 return err
573 }
574 if !fi.IsDir() {
575 return errors.New(source + " is not a directory")
576 }
577 err = os.MkdirAll(dest, fi.Mode())
578 if err != nil {
579 return err
580 }
581 entries, err := ioutil.ReadDir(source)
582 for _, entry := range entries {
583 sfp := filepath.Join(source, entry.Name())
584 dfp := filepath.Join(dest, entry.Name())
585 if entry.IsDir() {
586 err = copyDir(sfp, dfp)
587 if err != nil {
588 fmt.Println(err)
589 }
590 } else {
591 err = copyFile(sfp, dfp)
592 if err != nil {
593 fmt.Println(err)
594 }
595 }
596 
597 }
598 return nil
599 }
600 
601 // 3. 时间处理
602 // import "time"
603 func TestTimeDemo(t *testing.T) {
604 // Parse
605 postDate, err := time.Parse("2006-01-02 15:04:05", "2015-09-30 19:19:00")
606 fmt.Println(postDate, err)
607 
608 // Format
609 assert.Equal(t, "2015/Sep/30 07:19:00", postDate.Format("2006/Jan/02 03:04:05"))
610 assert.Equal(t, "2015-09-30T19:19:00Z", postDate.Format(time.RFC3339))
611 }
612 
613 // 4. 正则表达式
614 // import "regexp"
615 func TestRegexp(t *testing.T) {
616 // 查找匹配
617 re := regexp.MustCompile(`(\d+)-(\d+)`)
618 r := re.FindAllStringSubmatch("123-666", -1)
619 
620 assert.Equal(t, 1, len(r))
621 assert.Equal(t, "123", r[0][1])
622 assert.Equal(t, "666", r[0][2])
623 
624 }
625 
626 func main() {
627 helloWorld()
628 }

猜你喜欢

转载自www.cnblogs.com/xxllzizi/p/12550136.html