GO实例

一、基础知识

package main

import (
    "fmt"
)
/**

1.变量声明
var var_name type

2.全局变量
var (
    name1 type
    name2 type
    ...
)

3.变量初始化
var name type = value
var name = value
name := value

4.变量赋值
var name type
name = value
i, j = j, i

5.匿名变量
_, i := value, 1

6.定义常量
const name type = value
const name = value
const (
    name type = value
    name = value
)
const c1, c2,... [type] = v1, v2,...

7.预定义常量true false iota
const (
    a = iota   // a = 0
    b = iota   // b = 1
    ...        ...
)

8.枚举
const (
    Sunday = iota
    Monday
    Tuesday
    Wednseday
    ...
)

9. go语言的类型
1).bool: true false
2).整型: int8 uint8 int16 uint16 int32 uint32 int64 uint64 int uint(平台相关)
   uintptr(整型指针,32-4bytes 64-8bytes)
3).浮点数: float32 float64
4).复数: complex(real, imag) a + bj  real(z) imag(z)
5).字符串
6).字符: byte(utf-8) rune(unicode)
7).数组: var arr_name [len]type   arr_name := [len]type{...}
   值类型,副本传递
8).切片: var slice_name []type = arr[:]  slice_name := make([]type, len, [cap])
   slice_name := []type{...}
   避免内存重分配以及复制操作,设置合理的capacity,
   len() cap() append(slice, ...) copy(src, dest)
9).map: var map_name map[keyType] valueType  map_name = make(map[kType] vType)
   map_name = map[ktype] vtype {k: v,...}
   delete(map_name, key)
   v, exist = map_name[key]

10.流程控制
1). 条件: if codition  else if else
2). 选择: switch { case v: }  注意fallthrough关键字
3). 循环: for ; ;
4). 跳转: goto label

11. 函数
func FuncName(p1 type, p2 type) (r1 type, r2 type) {

}
小写字母开头的函数只在本包中可见,大写开头的才能让其它包访问
func name(args ...type)
...interface{} 任意类型不定参数
多返回值
匿名函数和闭包
func(p1,...type) type {
    ...body
}
可直接赋值给变量或直接运行

12. 错误处理
1). error接口
2). defer: 遵照先进后出原则
3). panic和recover

**/

func main() {
    _, i := 1, 2
    fmt.Println(i)
    
    func(p string) {
        fmt.Println(p)
    }("匿名函数")
            
    a := func() func() {
        j := 2
        return func() {
            fmt.Println(i * j)
        }

    }()
                                                        
    a()
    i = 10
    a()
}

二、flag命令行解析

package main

import (
    "flag"
    "fmt"
)

/**

flag.Type(stringName, value, usage)
flag.TypeVar(&var, stringName, value, usage)

-/--flag
-/--flag=v
-/--flag v     (不能用于非布尔类型)

*/

func main() {
    var i = flag.Int("i", 0, "usage ./test-150607 -i <int>")
    var k int
    flag.IntVar(&k, "k", 0, "usage ./test-150607 -k <int>")
    var opt = flag.String("opt", "*", "usage ./test-150607 -opt=<string>")
    flag.Parse()
    fmt.Println(*i, k, *opt)
}

三、文件操作

package main

// 文件操作实例
/**
io
err != io.EOF
*/

import (
    "fmt"
    "os"
)
func main() {
    fileStr := "/tmp/test"
    write(fileStr)
    defer func() {
        r := recover()
        if r != nil {
            fmt.Println("error ===> ", r)
        }
    }()
    fmt.Println(read(fileStr))
    deleteFile(fileStr)
}

func write(fileStr string) {
    // create file
    file, err := os.Create(fileStr)
 
    defer file.Close()
 
    if err != nil {
        fmt.Println(fileStr, err)
        return
    }

    // write to file
    file.WriteString("golang's file operation\n\r")
}

func read(fileStr string) string {
    file, err := os.Open(fileStr)
    
    defer file.Close()
        
    content := ""
            
    if err != nil {
        fmt.Println(fileStr, err)
        return content
    }
                
    buf := make([]byte, 1024)
    
    for {
        n, _ := file.Read(buf)
        if n == 0 {
            break
        }
        content += string(buf[:n])
    }
            
    return content
}

func deleteFile(fileStr string) {
    err := os.Remove(fileStr)
    if err != nil {
        panic(err)
    }
}

bufio读写操作:

package main

/**
使用bufio对文件进行读写操作
*/

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    fileStr := "/tmp/test"
    file, err := os.Open(fileStr)
    defer file.Close()
    r := bufio.NewReader(file)
    
    if err != nil {
        fmt.Println("error===>", err)
        panic(err)
    }
        
    wFile, wErr := os.Create("/tmp/test.bak")
    defer wFile.Close()
    w := bufio.NewWriter(wFile)
            
    if wErr != nil {
        panic(wErr)
    }
            
    buf := make([]byte, 1024)
    for {
        n, _ := r.Read(buf)
        if n == 0 {
            break
        }
        w.Write(buf)
        w.Flush()
    }
}

io/ioutil读写文件

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    fileStr := "/tmp/test"
    buf, rErr := ioutil.ReadFile(fileStr)
    if rErr != nil {
        panic(rErr)
    }
    fmt.Println(string(buf))
    
    ioutil.WriteFile("/tmp/test.bak", buf, 0644)
}

path/filepath对文件路径和目录进行处理

四、面向对象

package main

import (
    "fmt"
)

/**

1.类型系统
1.1. 为类型添加方法
go语言与c语言类似,要引用传递必须通过指针传递

1.2. 值语义和引用语义
引用类型:切片、map、channel、interface

1.3. 结构体

2. 初始化类

3. 匿名组合(没有继承,使用组合)

4. 可见性: 大写相当于public

5. 接口
5.1 非侵入式接口
如果一个类实现类该接口要求的所有函数,那么该类就实现类该接口
5.2 接口赋值
将对象赋值给接口;将接口赋值给接口
5.3 接口查询
object.(类型): object是否属于某个接口
5.4 接口组合
5.5 Any类型
var v interface = ...
*/

//1.1
type integer int

func (i integer) greaterThan(o integer) bool {
    return i > o
}

func (i *integer) increment() {
    *i += 1
}

// 1.3
type Person struct {
    id   int
    name string
}

// 3.
type Base struct {
    id int
}

func (base *Base) m1() bool {
    return base.id > 0
}

// 4.

type Foo struct {
    Base
    // *Base
    name string
}

func (foo *Foo) m1() bool {
    return foo.Base.m1()
}

func (p *Person) speak() {
    fmt.Println("my name is ", p.name)
}

// 5.1
type IBase interface {
    Search(key string) string
}

type SearchEngine struct {
}

func (se *SearchEngine) Search(key string) string {
    return key + "..."
}

// 5.4
type Reader interface {
    Read(bytes []byte) (n int, err error)
}
type Writer interface {
    Write(bytes []byte) (n int, err error)
}
type ReaderWriter interface {
    Reader
    Writer
}

func main() {
    var i integer = 10
    fmt.Println(i.greaterThan(9))
    i.increment()
    fmt.Println(i)
    
    // 结构体实例化
    // p := new(Person)
    // p := &Person{}
    // p := &Person{1, "sosop"}
    p := &Person{id: 1, name: "sosop"}
    p.speak()
    
    var se IBase = new(SearchEngine)
    fmt.Println(se.Search("google"))
    
    var a interface{} = 100
    
    switch t := a.(type) {
    case int:
        fmt.Println("int")
    case string:
        fmt.Println("string")
    default:
        fmt.Println(t)
    }
}

面向对象实例:

package mlib

import (
    "errors"
)

type MusicEntry struct {
    Id     string
    Name   string
    Artist string
    Source string
    Type   string
}

type MusicManager struct {
    musics []MusicEntry
    }

    func NewMusicManager() *MusicManager {
        return &MusicManager{make([]MusicEntry, 0, 20)}
    }

    func (m *MusicManager) Len() int {
        return len(m.musics)
    }

    func (m *MusicManager) Get(index int) (music *MusicEntry, e error) {
        if index < 0 || index >= m.Len() {
            return nil, errors.New("index out of range.")
        }
        return &m.musics[index], nil
    }

    func (m *MusicManager) Find(name string) *MusicEntry {
        if m.Len() == 0 {
            return nil
        }
        for _, music := range m.musics {
            if music.Name == name {
                return &music
            }
        }
        return nil
    }

    func (m *MusicManager) Add(music *MusicEntry) {
        m.musics = append(m.musics, *music)
    }

    func (m *MusicManager) Remove(index int) *MusicEntry {
        if index < 0 || index >= m.Len() {
            return nil
        }

        removeMusic := &m.musics[index]
        m.musics = append(m.musics[:index], m.musics[index+1:]...)
        return removeMusic
    }

another:

package play

import (
    "fmt"
    "time"
)

type Player interface {
    Play(source string)
}

func Play(source, mtype string) {
    var p Player

    switch mtype {
    case "MP3":
        p = &MP3Player{}
    default:
        fmt.Println("Unsupported music type: ", mtype)
        return
    }
    p.Play(source)
}

type MP3Player struct {
    stat    int
    process int
}

func (p *MP3Player) Play(source string) {
    fmt.Println("Playing MP3 Music", source)
    p.process = 0
    for p.process < 100 {
        time.Sleep(time.Millisecond * 100)
        fmt.Print(".")
        p.process += 10
    }
}

五、并发变成
1.县城间的通信方式: 共享内存、消息传递
2.channel:类型相关

package main

import (
    "fmt"
)

/**

1. channel:
var chanName chan type
ch = make(chan type)
chs = make([]chan type, len)
写入:ch <- value
读出:value := <- ch

2. select
监控文件句柄,有io动作,则被返回
select {
case <- ch1:
todo
case ch2 <- value:
todo
default:
todo
}

3.channel的缓冲
c := make(chan type, buffer length)

4.超时处理可以利用select

5.传递channel

6.单项channel
var ch1 chan<- type
var ch2 <-chan type

chR := chan<- type(ch)
chW := <-chan type(ch)

7.channel closed
close(ch)
v, isClosed := <-ch

8.同步
同步锁:Mutex sync.Mutex  sync.RWMutex(lock unlock)

9.全局唯一:sync.Once



*/
 
func main() {
    chs := make([]chan int, 10)

    var counter int = 0

    for i := 0; i < len(chs); i++ {
        chs[i] = make(chan int)
        go add(chs[i], i+1)
    }

    for _, v := range chs {
        counter += <-v
    }

    fmt.Println(counter)

}
 
func add(ch chan int, value int) {
    ch <- value
}
sosop hou 04 June 2015
blog comments powered by Disqus