goroute之间通信-共享全局变量(理解go的多并发)

1、go语言中goroute之间通信有两种方式:

  • 通过全局变量,这种方式得加锁
  • 通过channel进行通信

下面是一个通过全局变量进行通信的例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package main

import (
	"fmt"
	"sync"
	"time"
)

var (
	m    = make(map[int]uint64)
	lock sync.Mutex
)

type task struct {
	n int
}

func calc(t *task) {
	var sum uint64
	sum = 1
	for i := 1; i < t.n; i++ {
		sum *= uint64(i)
	}
	lock.Lock()
	m[t.n] = sum
	lock.Unlock()
}

func main() {
	for i := 0; i < 20; i++ {
		t := &task{n: i}
		go calc(t)
	}
	time.Sleep(10 * time.Second)

	lock.Lock()
	for k, v := range m {
		fmt.Printf("%d!=%v\n", k, v)
	}
	lock.Unlock()

}

输出结果如下:

……

阅读全文

接口应用-可扩展输出方式的日志系统

利用接口实现一个可扩展的日志系统:

1、日志对外接口:

本例中定义一个日志写入的接口(LogerWriter),要求写入设备必须遵守这个接口协议(实现这个接口)才能被日志器(Logger)注册。日志器有ResgisterWriter()和Log()两个方法,ResgisterWriter()方法将日志写入器(LogWriter)注册到日志器中,log()方法进行日志的输出,这个函数会将日志写入到所有已经注册的日志写入器(LogWriter)中。本例中简单实现文件和输出到终端这两种方式。

……

阅读全文

go语言实现通用链表

实现通用链表

  1. link.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package main

import "fmt"

type LinkNode struct {
	data interface{}
	next *LinkNode
}

type Link struct {
	head *LinkNode
	tail *LinkNode
}

func (p *Link) InsertHead(data interface{}) {
	node := &LinkNode{
		data: data,
		next: nil,
	}
	if p.tail == nil && p.head == nil {
		p.head = node
		p.tail = node
		return
	}
	node.next = p.head
	p.head = node

}

func (p *Link) InsertTail(data interface{}) {
	node := &LinkNode{
		data: data,
		next: nil,
	}

	if p.tail == nil && p.head == nil {
		p.head = node
		p.tail = node
		return
	}
	p.tail.next = node
	p.tail = node

}

func (p *Link) Trans() {
	q := p.head
	for q != nil {
		fmt.Println(q.data)
		q = q.next
	}

}

func (p *Link) Getlen() {
	q := p.head
	m := 0
	for q != nil {
		m++
		q = q.next
	}
	fmt.Println(m)
}
  1. main.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

func main() {
	var l Link
	for i := 1; i < 10; i++ {
		l.InsertTail(i)
		//l.InsertHead(i)
		//l.InsertTail(fmt.Sprintf("str %d", i))

	}

	l.Trans()
	l.Getlen()
}
……

阅读全文

go语言接口实现应用-Sort接口

go语言接口:

go语言的接口设计是非侵入式的,接口的编写者无需知道接口被那些类型实现。而接口实现者只需要知道实现的是什么样子的接口,但无须指明实现哪一个接口。不像其他语言需要用implement来指出实现了哪个接口。有几个需要注意的地方:

  1. interface本身也是一种类型,可以定义一组方法,但是接口中不能包含任何的变量
  2. 必须实现了接口中的所有方法,才能调用接口
  3. 实现接口的方法必须和接口中定义的方法格式一致,包括函数名和返回值等。

多态

一种的事物的多种形态,都可以按照统一的接口进行操作。

理解:比如go语言sort包中提供了一个排序的Sort接口,它可以对整数,浮点数,字符串等进行排序,只要实现接口中定义的下面三个方法,就可以调用Sort方法进行排序,不用每一种类型都去定义一种实现的方法。

我们从go网站上面可以查到Sort方法是这样:func Sort(data Interface)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
type Interface interface {
    // Len is the number of elements in the collection.
    // Len 为集合内元素的总数
    Len() int
    // Less reports whether the element with
    // index i should sort before the element with index j.
    //
    // Less 返回索引为 i 的元素是否应排在索引为 j 的元素之前。
    Less(i, j int) bool
    // Swap swaps the elements with indexes i and j.
    // Swap 交换索引为 i 和 j 的元素
    Swap(i, j int)
}
……

阅读全文