go语言

准备看6.824, 竟然要先学go语言

 

首先是不同的定义方式,int在后面,这样a/b/c都是Int类型,当然也不需要分号结尾
var a, b, c int

函数定义, 开始看的只有num2还以为打错了,结果竟然也是一起定义成了int类型
func max(num1, num2 int) int {
  ...
}
匿名函数
func max(x int){
  // 函数自动执行,并且x=2
}(2)

声明长度为10的float32类型数组,名为balance。如果要初始化直接在后面加个大括号即可。
var balance [10] float32

int型指针, 用法同c语言
var ip *int
结构体
type Books struct {
   title string
   author string
   subject string
   book_id int
}

切片, 类似vector可以不指定容量,指定的话也只是长度,可以扩展
s :=[] int {1,2,3}
s :=make([]int,3,5)    // 长度3,容量5
len(s) cap(s)          // 分别计算长度,与容量
s[l:r]                 // 获取闭区间l到开区间r的切片
append                 // 用于追加

range进行遍历。对于遍历数组nums,i是序列号,num是值。如果遍历map,则是key与value。
for i, num := range nums {
       if num == 3 {
           fmt.Println("index:", i)
       }
   }

map,创建map的两种方式,以及初始化的方式
 var countryCapitalMap map[string]string /*创建集合 */
    countryCapitalMap = make(map[string]string)
    countryCapitalMap [ "France" ] = "巴黎"

类型转换
var z int;
float32(z); //转换为float32

通过go 关键字开启新线程,实现并发
例如:say是一个输出字符串的函数
 go say("world")
 say("hello")
则会没有先后顺序的输出world 和 hello

通道。可用来同步运行和通讯。
ch := make(chan int)
ch <- v    // 把 v 发送到通道 ch
v := <-ch  // 从 ch 接收数据 并把值赋给 v
通道缓冲区。与通道唯一区别就是,而发送端可以把数据发送到缓冲区,若缓冲区满了,就会如同不带缓冲区一样一直阻塞
ch := make(chan int, 100)
select {
    case  <- ch1:
        // 从ch1读取到数据,则走本条路
    case ch2 <- x:
         //  数据成功写入到ch2,则走本条路
     default:
        // 若都未成功则走本条路
}
/*
若case中有未阻塞的则走任意未阻塞的case
若都阻塞,则有default就走default,否则一直阻塞
*/

:=与=的区别
:=会直接把类型赋值过去
=只会把值赋值过去

iota初始为0,下面的依次加一
const{
  Follower = iota  //0
  Candidate        //1  
  Leader           //2
}

time.Timer是一个定时器,原理也是通道,时间一到从通道注入

interface{}则可以看做C语言中void*

方法需要在func与函数名之间声明接受者
type Circle struct {
  radius float64
}
//该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea() float64 {
  return 3.14 * c.radius * c.radius
}

反射
package main

import "reflect"
import "fmt"

type Student struct {
    name string
    id  int 
}

func (stu *Student) SayName() {
    fmt.Println("My name is ",stu.name)
}

func (stu *Student) SayId() {
    fmt.Println("My id is ",stu.id)
}

// 如何操作一个未知的类型 -> 反射
func Print(x interface{}) {
    v := reflect.ValueOf(x)
    t := v.Type()
    fmt.Println("value = ",v,"type = ",t);  // 输出 value =  &{Xiao Ming 1} type =  *main.Student

    // 获得方法个数,遍历每个方法,一般可以放到map中,方便之后反射
    for i :=0; i < v.NumMethod(); i++ {
        fmt.Println("Method name :",t.Method(i).Name," Method type:",v.Method(i).Type()) // 输出 Method name : SayId  Method type: func()
        v.Method(i).Call([]reflect.Value{})     // 输出 My id is  1
    }   
}

func main() {
    fmt.Println("Hello, world!")

    stu := &Student{}
    stu.name="Xiao Ming"
    stu.id=1

    stu.SayName()   // 输出 My name is XiaoMing
    stu.SayId()     // 输出 My id is 1

    Print(stu)
}
posted @ 2019-11-06 15:34  注册以后还能改吧  阅读(154)  评论(0编辑  收藏  举报