一、基础知识
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
}