Go语言入门DEMO

目录先干为敬,主要来自菜鸟教程
在这里插入图片描述

import "fmt"

type PeopleInfo struct {
	name string
	age  int
}

type Father interface {
	Hear(word string)
	Speak() string
	ChangeName(name string)
}

//  (p PeopleInfo)称为接收器,一个函数只有一个接收器
//  推荐此类写法为struct 扩展成员方法
//  支持指针类型(适合大对象)、非指针类型(适合小对象),本例子是非指针
func (p PeopleInfo) Hear(s string)  {
	fmt.Println("name: ",p.name,"hear: ",s)
}
func (p PeopleInfo) Speak() string{
	return "I do"
}
func (p *PeopleInfo) ChangeName(name string){
	p.name=name
}

type Person struct {
	name string
	age  int
}


import (
	"fmt"
	"sync"
)

var (
	count      int
	pos        int
	countGuard sync.Mutex
)

func get(count *int) int {
	countGuard.Lock()
	defer countGuard.Unlock()
	return *count
}

func add(count *int) {
	countGuard.Lock()
	defer countGuard.Unlock()
	*count++
}

func main() {
	nums:=100
	var group sync.WaitGroup
	// 两种增加计数的方式均可
	group.Add(nums)
	for i := 0; i < nums; i++ {
		// group.Add(1)
		go func() {
			defer group.Done()
			for j := 0; j < 100; j++ {
				// 线程安全
				add(&count)
				// 线程不安全
				pos++
			}
		}()
	}
	group.Wait()

	fmt.Println(get(&count))
	fmt.Println(pos)

}

import "fmt"
import com "common"

func main(){
	// 实例化接口
	var father com.Father
	// PeopleInfo实现了Father接口,可以直接转成father
	father = new(com.PeopleInfo)
	fmt.Println(father)
	father.Hear("do you love me")
	fmt.Println("name: ",nil,"speak: ",father.Speak())
	father.ChangeName("huang")
	fmt.Println(father)
}


import (
	"bytes"
	"fmt"
	"reflect"
	"strconv"
)

type actor struct {
	age  int
	name string
}
// 反射的意义:可获得类的信息,类变量、方法等信息,并作出修改
// reflect.TypeOf():获取类型信息
// reflect.ValueOf() : 获取反射值对象(需要传入结构体或者指针)
func main() {
	a := actor{11, "huangcheng"}
	var b bytes.Buffer
	fmt.Println(reflect.TypeOf(a).Name(), reflect.TypeOf(a).Kind(), reflect.TypeOf(a).Field(1))
	fmt.Println(reflect.ValueOf(a).Kind())
	b.WriteString("{")
	writeAny(&b, reflect.ValueOf(a))
	b.WriteString("}")
	fmt.Print(b.String())

}

func writeAny(b *bytes.Buffer, value reflect.Value) {
	switch value.Kind() {
	case reflect.String:
		b.WriteString(value.String())
	case reflect.Int:
		b.WriteString(strconv.FormatInt(value.Int(), 10))
	case reflect.Struct:
		for i := 0; i < value.NumField(); i++ {
			b.WriteString("\"")
			b.WriteString(value.Type().Field(i).Name)
			b.WriteString("\":")
			writeAny(b, value.Field(i))
			if i < value.NumField()-1 {
				b.WriteString(",")
			}
		}
	}
}

import "fmt"
/**
 求素数
 */
func main(){
	countPrimes(10)
}
func countPrimes(n int) int {
	compositeList :=make([]bool,n)
	result :=0
	for i:=2;i<n;i++{
		if !compositeList[i]{
			fmt.Println(i)
			result++
			for j:=2;j*i<n;j++{
				compositeList[j*i]=true
			}
		}
	}
	return result
}

import (
	"common"
	"fmt"
	"testing"
)

func BenchMark_Alloc(b *testing.B){
	b.ResetTimer()
	b.StopTimer()
	b.StartTimer()
	for i:=0;i<b.N;i++{
		var person common.Person
		fmt.Println(person)
	}

}

import (
	"errors"
	"fmt"
	"time"
	"testing"
)
// channel 一定是先有接受者R1,才有发送者R2;若只有R2报错
// R1与R2是不同的线程;同一个报错
// go test -v test.go 执行测试案例并展示日志
// go test -v -run TestChannel test.go 执行test.go中的TestChannel方法

func TestChannel(t *testing.T) {
	ch := make(chan string)
	go server(ch)
	code, error := client(ch)
	if error != nil {
		fmt.Println(error)
	} else {
		fmt.Println(code)
	}
	t.Log("helloworld")
}

func client(ch chan string) (string, error) {
	ch <- "huang"
	fmt.Println("client send")
	select {
	case ack := <-ch:
		return ack, nil
	case <-time.After(time.Second):
		return "", errors.New("server Time Out")
	}
}

func server(ch chan string) {
	time.Sleep(5 * time.Second)
	fmt.Println("server Received: ", <-ch)
	// 给客户端回消息,否则客户端超时
	ch <- "roger"
}


import (
	"fmt"
	"testing"
)

func TestConstant(t *testing.T) {
	// go语言会自动找string()方法
    fmt.Println(cpu)
	fmt.Println(gpu.String())
	fmt.Printf("%d ", none)
	fmt.Printf("%d ", cpu)
	fmt.Printf("%d ", gpu)
	fmt.Printf("%d ", now)


}

// 根据数字映射字符串(应用场景:接口定义为数字类型,处理时候转换成具有实际含义的字符串)
// 把int类型,取别名为ChipType
type ChipType int

const (
	none ChipType = 1<<iota
	cpu
	gpu
	now =iota
)

func (c ChipType) String() string {
	switch c {
	case none:
		return "NONE"
	case cpu:
		return "CPU"
	default:
		return "N/A"
	}
}

// 基础类

import (
	"errors"
	"fmt"
	"time"
)
// channel 一定是先有接受者R1,才有发送者R2;若只有R2报错
// R1与R2是不同的线程;同一个报错

func main() {
	ch := make(chan string)
	go server(ch)
	code, error := client(ch)
	if error != nil {
		fmt.Println(error)
	} else {
		fmt.Println(code)
	}
}

func client(ch chan string) (string, error) {
	ch <- "huang"
	fmt.Println("client send")
	select {
	case ack := <-ch:
		return ack, nil
	case <-time.After(time.Second):
		return "", errors.New("server Time Out")
	}
}

func server(ch chan string) {
	time.Sleep(5 * time.Second)
	fmt.Println("server Received: ", <-ch)
	// 给客户端回消息,否则客户端超时
	ch <- "roger"
}

import "fmt"

func main() {
	// 通过判断错误信息来处理异常
	res, msg := divide(0, 10)
	if msg == "" {
		fmt.Println(res)
	} else {
		fmt.Println(msg)
	}
	recov()
	fmt.Println("已完成")

}

func recov(){
	// 被延迟执行
	defer func(){
		// 捕获Panic信息,打印
		err :=recover()
		fmt.Println(err)
	}()
	// runtime抛出异常导致宕机
	a := 1
	b := 0
	c := a / b
	fmt.Println(c)
	// 手工Panic导致宕机
	panic("crash")
}

func divide(dividor int, dividee int) (result int, ErrMsg string) {
	if dividor == 0 {
		// 组个对象,调用方法,生成错误信息
		data := DivideInfo{dividee, dividor}
		ErrMsg = data.Error()
		return
	}
	return dividee / dividor, ""
}

type DivideInfo struct {
	// 分子
	dividee int
	// 分母
	dividor int
}

func (d DivideInfo) Error() string {
	return fmt.Sprintf("divider is error,dividee: %d", d.dividee)
}

import (
	"fmt"
	"time"
)

// 需要声明是哪种类型的channel
func fibonacci(n int , c chan int){
	x,y:=0,1
	for i:=1;i<=n;i++{
		c <- x
		//time.Sleep(1000*time.Millisecond)
		x,y=y,x+y
	}
	// 关闭通道,否则主线程会一直夯住
	close(c)
}
func main(){
	c :=make(chan int,1)
	// 开启goroutine
	go fibonacci(10,c)

	// main线程中,range函数会一直阻塞在通道处取数
	for i:= range c{
		time.Sleep(time.Second)
		fmt.Print (i," ")
	}

}

import "fmt"

func main() {
	// 函数调用,非指针类型不改变原值
	i := 1
	change(i)
	fmt.Println(i)
	// 函数调用
	maxValue := max(2, 3)
	fmt.Println(maxValue)
	// 匿名函数作为实际参数
	getMax := func(m, n int) int {
		if m > n {
			return m
		} else {
			return n
		}
	}
	fmt.Println(getMax(3, 4))
	// 计算圆的面积
	var c Cycle
	c.radius = 5
	fmt.Println(c.getArea())
	c.changeRadius(10)
	fmt.Println(c.getArea())
	changeRadius2(&c, 20)
	fmt.Println(c.getArea())
}

func change(a int) {
	a = 2
}

// 取最大,函数的返回值放在了最后,Java放中间
func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

// 使用type+struct声明结构体,类似JavaBean
type Cycle struct {
	radius float64
}

func (c Cycle) getArea() float64 {
	return c.radius * c.radius * 3.14
}

// 以下两个方法是等效的,都需要传入指针,第一种对于调用者来说,更好理解
func (c *Cycle) changeRadius(r float64) {
	c.radius = r
}
func changeRadius2(c *Cycle, r float64) {
	c.radius = r
}

import (
	"fmt"
)

func main() {
	list := []int{4, 5, 6, 7, 8, 9}
	ch := make(chan int, 2)
	// go开启线程,异步处理
	go sum(list[:len(list)/2], ch)
	go sum(list[len(list)/2:], ch)
	x, y := <-ch, <-ch
	fmt.Println(x, y, x+y)
}

// 传递通道给sum方法,存储临时计算的数据,而不用每次返回值
func sum(list []int, ch chan int) {
	sum := 0
	for i := range list {
		sum += list[i]
	}
	ch <- sum
}

import "fmt"

type PeopleInfo struct {
	name string
	age  int
}

type Father interface {
	hear(word string)
	speak() string
	changeName(name string)
}

func main(){
	// 实例化接口
	var father Father
	// PeopleInfo实现了Father接口,可以直接转成father
	father = new(PeopleInfo)
	fmt.Println(father)
	father.hear("do you love me")
	fmt.Println("name: ",nil,"speak: ",father.speak())
	father.changeName("huang")
	fmt.Println(father)

}
//  (p PeopleInfo)称为接收器,一个函数只有一个接收器
//  推荐此类写法为struct 扩展成员方法
//  支持指针类型(适合大对象)、非指针类型(适合小对象),本例子是非指针
func (p PeopleInfo) hear(s string)  {
	fmt.Println("name: ",p.name,"hear: ",s)
}
func (p PeopleInfo) speak() string{
	return "I do"
}
func (p *PeopleInfo) changeName(name string){
	p.name=name
}

import (
	"fmt"
	"time"
)

// 结构体在本质上是定义好Key的键值对
type Person struct {
	name string
	age  int
}

func main() {
	// 编译器会根据值进行变量类型(int)指定
	for i := 1; i < 2; i++ {
		fmt.Println("forEach")
	}
	//range 遍历
	stringList := []string{"aa", "bb"}
	for i, v := range stringList {
		fmt.Println(i, v)
	}
	fmt.Println(&stringList[1], &stringList[0])
	// 实例化结构体的两种方法
	// 1、var声明
	var people Person
	people = Person{"huang", 1}
	var people1 Person
	people1.age = 11
	fmt.Println(people)

	// 2、使用new或者&,实例化结构体,获得指针对象(可忽略键的名称,直接赋值)
	var people2 *Person
	// 声明指针后直接赋予取值会Panic
	people2.name = "kevin"  // 会PANIC
	people2 = &Person{"huang", 12}
	people3 := new(Person)
	people3.name = "kevin"
	people3.age = 20
	// 声明切片的方法,初始化长度、容量
	slice := make([]Person, 2, 4)
	slice = append(slice, people1, *people2, *people2, *people3, *people3)
	for i, v := range slice {
		fmt.Print(i, v)
	}
	// 切片的截取操作
	// SLICE[A:]  // 从A切到最尾部
    // SLICE[:B]  // 从最开头切到B(不包含B)
    // SLICE[:]   // 从头切到尾,等价于复制整个SLICE
	fmt.Println(len(slice), cap(slice))
	fmt.Println(slice[:3])
	fmt.Println(slice[3:cap(slice)])

	// 得到指针数组的方式,遍历时候注意共享变量v的使用
	intList := []int{1, 2, 3}
	var cpList []*int
	for i, _ := range intList {
		cpList = append(cpList, &intList[i])
	}
	for _, v := range intList {
		go func() {
			fmt.Printf("%d ", v)
		}()
	}
	time.Sleep(1000 * time.Millisecond)
	fmt.Println(cpList)
	// 切片使用问题?
	// 1、修改切片元素,前者修改成功,后者修改不成功,为啥?
	slice[3].name = "cheng"
	p := slice[3]
	p.name = "ravin"

	// 2、 ==是比较地址么?那切片中的person地址一样么?那修改slice[3]会影响slice[4]么?
	fmt.Println(slice[5] == slice[6])

	// 切片复制的方法
	sliceCp := make([]Person, len(slice), cap(slice))
	copy(sliceCp, slice)
	fmt.Println(slice)
	fmt.Println(sliceCp)

	// 字符串的操作
	target := "ABa"
	var target1 = "abcd"
	fmt.Println("target:", len(target))
	fmt.Println("target1:", len(target1))
	lastIndex := len(target) - 1
	for i := range target {
		if i == lastIndex {
			fmt.Println(int(target[i]))
		}
	}

}
import (
	"fmt"
)

// 实例化CountryMap时候,不会自动实例化value
type CountryMap struct {
	value map[string]string
}

// 构造方法
func newCountryMap() *CountryMap {
	return &CountryMap{
		value: make(map[string]string),
	}
}

// 成员方法:put
func (c *CountryMap) put(k string, v string) {
	// 初始化
	if c.value == nil {
		fmt.Println("initial")
		c.value = make(map[string]string, 2)
	}
	c.value[k] = v
}

// 成员方法:get,直接使用k找v
func (c *CountryMap) get(k string) string {
	capital, ok := c.value[k]
	if ok {
		return capital
	} else {
		fmt.Println("could not find,", k)
		return ""
	}
}

func main() {
	countryMap := newCountryMap()
	countryMap.put("china", "Beijing")
	countryMap.put("american", "Washington")
	fmt.Println(countryMap.get("china"))
	for k, v := range countryMap.value {
		fmt.Println(k, v)
	}
}
import "fmt"

type People struct {
	name string
	age  int
}

func main() {
	// 声明类型指针,此时为nil
	var ptr *string
	// 初始化初值后,才能*取值或赋值,否则报空指针异常
	// *ptr ="huang"
	var bb = "bb"
	// 地址赋值
	ptr = &bb
	// 地址是一样的
	fmt.Println(&bb)
	fmt.Println(ptr)
	// 变量赋值
	*ptr = "cc"
	fmt.Println("bb:", bb, " ptr:", *ptr)

	// 指针交换
	var a = 100
	var b = 200
	swap(&a, &b)
	fmt.Println(a, b)
	fmt.Println(twoParams(&a, &b))

	m := "huang"
	n := "cheng"
	swapB(&m, &n)
	fmt.Println(m, n)

	// 声明数组指针
	people := People{"kevin", 13}
	var tab [16]*People
	for i := range tab {
		// 初始化
		tab[i] = &people
		fmt.Print(*tab[i])
	}

}

// 交换指针对应的值
func swap(a, b *int) {
	var temp int
	// 取值赋给temp
	temp = *a
	*a = *b
	*b = temp
}

func swapB(a, b *string) {
	*a, *b = *b, *a
}

// 函数返回两个参数
func twoParams(a, b *int) (c, d int) {
	return *b, *a
}

import (
	"errors"
	"fmt"
	"time"
)

func main() {
	ch := make(chan string)
	go Server(ch)
	for i:=0;i<5;i++{
		code, error := Client(ch)
		if error != nil {
			fmt.Println(error)
		} else {
			fmt.Println(code)
		}
	}
}

func Client(ch chan string) (string, error) {
	ch <- "huang"
	select {
	case ack := <-ch:
		return ack, nil
	case <-time.After(time.Second):
		return "", errors.New("server Time Out")
	}
}

func Server(ch chan string) {
	for {
		fmt.Println("server Received: ", <-ch)
		// 给客户端回消息,否则客户端超时
		ch<-"roger"
	}
}
import "fmt"

func main() {

	fmt.Println("Hello, World!")
	// string
	var a = "aa"
	// int
	var b, c = 1, 2
	// bool
	var d1 = true
	var d2 = false
	d3 := d1 && d2
	// map
	var e map[string]int
	// point
	var f *int
	// 无符号整数,不能接负数
	var g uint16 = 1
	// float32有精度损失
	var m float32 = 0.222
	fmt.Println(a, b, c, d1, d2, d3, e, f, g, m)

	// 浮点数测试
	x := 1.75
	y := 2.2
	sum := x * y
	fmt.Println(float32(sum))
	testFloat()

	const (
		a1 = iota
		b1 = iota
		d  = 3
		c1 = iota
	)
	fmt.Println(a1, b1, c1)
}

func testFloat() {
	// 0.2不能被二进制(科学计数法)精确表示,浮点数默认是float64
	a := float64(0.2)
	a += 0.1
	a -= 0.3
	var i int
	for i = 0; a < 1.0; i++ {
		a += a
	}
	fmt.Printf("After %d iterations, a = %e\n", i, a)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值