目录先干为敬,主要来自菜鸟教程
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)
}