Go学习日记 :第一章 基础篇

1.变量定义
 var a int = 1 // var a,b,c =1,"2",4
 编译器可以自动识别类型

 a,b := 1,2(只能初次定义使用,包外部不可用)
 
 var (
  a = '1'
 )

2.内建变量类型
  bool、string
  无符号:(u)int,(u)int8,(u)int16,(u)int32,(u)int64,uintptr 指针
  byte(8位),rune (字符型)32位
  float32,float64,complex64(复数,实部和虚部分别是32位)、complex128(复数,实部和虚部64位)
  复数:

欧拉公式:

常量 

const a,b = 3,5
var c = int 
fmt.Print(int(math.Sqrt(a*b+c+d)))

枚举类型:
 
 go语言没有特殊的枚举关键字,所以用一组const来定义表示
 普通枚举:
 const(
  cpp =0
  java = 1
  py = 2
 )
 自增枚举:
 const(
  cpp = iota //自增值
  java
  py
 )
 复杂运算:
  //b,kb,mb,gb,tb,pb
    const(
        b = 1<<(10*iota)
        kb
        mb
        gb
    )
可以作为一个自增值的种子

判断语句 if
 
 if content,err := ioutil.ReadFile(filename);err=null{
  fmt.PrintIn(string(content))
 }else{
  fmt=PrintIn("content is err",err)
 }

 switch

 func grade(score int)string{
    g := ""
    switch{
     case score<0||score>100:
    panic(fmt.Sprint("Wrong scroe : %d", score))
    case score < 60:
        g = "F"
    case score< 80:
        g ="C"
    }
    return g
 }
 go语言的switch自带berak

 for
 
 for ; ; {}
 func printFile(){
   filname := "123.txt"
   file,err := os.Open(filename)
   if err!=nill{
   panic(err)
   }
   scanner=bufio.NewScanner(file)
   for scanner.Scan(){
    fmt.PrintIn(scanner.Text())
   }

 }

 指针
   var a int =2
   var pa *int =&a
   *pa =3
   指针不能运算
   Go语言只有值传递一种方式
   当 func f(pa *int)的时候,相当于把地址进行传递
   当 func f(cache Cache)的时候,相当于直接把cache里面pDate指针拷贝过去,都是指向data
   func swap(a,b *int){
   *b,*a=*a,*b
   }
   swap(&a,&b)

数组:
 var arr1 [3][4]int
 arr2 :=[4]int {3,4,5,6}
 arr3 :=[...]int{123,23,4,5}
 var arrs [3][4] int
 数组遍历:
  for i:=range arr3{  //for i/_,v :=range arr3
   fmt.PrintIn(arr3[i])
  }
  i是数组下标,v为值 类似于foreach
 数组是值类型
   [10]int 和[20]int 是不同类型
   调用func f(arr [10]int)会拷贝数组
   在go语言不直接使用数组,而使用切片
   
切片
   slice本身是没有数据的,是对底层array的一个视图
   实例:
    arr := [...]int{0,2,3,4,5,6}
    fmt.Println(arr[2:6],arr[:6],arr[2:],arr[:])
   还可以resilic
     s:=arr[2:6]
     s = s[:3]
     s=s[1:]
     s=arr[:]  //和指针相同
   slice的扩展:
    问题一:
     arr:=[...]int{0,1,2,3,4,5,6}
     s1:=arr[2,6]
     s2:=s1[3:5]

     s1=[2,3,4,5]  s2=[5,6]

cap=cap(s1)


 添加元素如果超过cap,系统会重新分配更大的底层数组
 由于值传递的关系,必须接受append的返回值
 s=append(s,val)

 var s []int //zero value for slice is nil
 s = append(s,2*i+1)//当cap每次装不下的时候会*2
 还可以这样创建:
  s2 :=make([]int,16) //len=6
  s3 :=make([]int,10,32) //len=10,cap=32
  copy: copy (s2,s1) //把s1拷贝到s2
  del:中间的下标3的元素: s2=append(s2[:3],s2[4:]...)
  从头和从尾去掉:
  front :=s2[0]
  s2=s2[1:]

  tail := s2[len(s2)-1]
  s2=s2[:len(s2)-1]

    如果创建一个长度为16的slice:
      s2 := make([]int,16)
    创建一个有10个元素,但是数组有32个长度
      s3 :=make([]int,10,32)
    删除下标为3的元素
     s2=append(s2[:3],s2[4:]...)
     len会改变,cap不会改变
    删除首尾:
     s2=s2[1:]
     s2=sw[:len(s2)-1 ]
     


 Map: 
   map[K]V,map[K1]map[K2]V


  声明实例:
  创建:
  map := map[string]string{
    "name":"123",
  }  
  var m2 map[string] int    //m2=nil
  m3 :=make(map[string]int)    //m3=empty map
  遍历:k在map中是无序的,是hash map,需要给key进行排序,把key取出来放到slice中,排序完再去遍历map
   for k,v/_,v/k :=range m{

   }
  取值:
   if name,ok:=m["name"];ok{
    fmt.Println(name,ok)
   }else{
   fmt.Println(name,ok)
   }
  删除:    
   delete(m,"name")
  map的key:
  1>map使用哈希表,必须可以比较相等
  2>除了slice,map,function的内建类型都可以作为key
  3>Struct类型不包括上述字段也可以作为key

  面向对象


   go语言仅支持封装,不支持继承和多态,没有class只有struct
   创建结构体:
     type treeNode struct{
     value int
     left,right *treeNode
     }
     func (node treeNode) print(){ //treeNode结构体内的方法,go语言都是传值的
   fmt.Println(node.value)
}
    实例化:
      root :=treeNode{}
      root.left=&treeNode{}
      root.right.left=new(treeNode)
      nodes:=[]treeNode{
        {value:2}
        {}
        {1,nil,nil},
      }
    工厂函数:
      funct createNode(value int )*treeNode{
       return &treeNode{value:value} //返回局部变量的地址
      }

接口:
  go语言是面向接口的编程语言,没有继承和多态,通过接口完成
  duck typing:描述事务的外部行为而非内部结构
  严格说go属于结构化类型系统,类似duck typing
  go语言的接口是由使用者定义
  接口类:

type Retriever interface {
	Get(url string) string  //在interface中不用加func
}
func download(r Retriever) string{  //使用者
	return  r.Get("http://www.imooc.com")
}

func main() {
	var r Retriever
	r=mock.Retrievers{"this is a fake imooc.com"}
	//r=mock.Retrievers{"this is a fake imooc.com"}
	r=real.Retriever{}
	fmt.Println(download(r))
	//fmt.Println(download(r))
}

实现类:

type Retriever struct {
	UserAgent string
	TimeOut time.Duration
}

func(r Retriever) Get(url string) string{
	resp,err:=http.Get(url)
	if err!=nil{
		panic(err)
	}
	result,err:=httputil.DumpResponse(resp,true)
	resp.Body.Close()
	if err!=nil{
		panic(err)
	}
	return  string(result)
}

在r的里面有两个内容,一个类型,一个值

func inspect(r Retriever){
	fmt.Printf("%T %v\n",r,r)
//第二种打印方式
	switch v:=r.(type) {
	case mock.Retrievers:
         fmt.Println("content:",v.Contentst)
	case *real.Retriever:
		fmt.Println("UserAgent:",v.UserAgent)

	}
}
func main() {
	var r Retriever
	inspect(r)
	r=mock.Retrievers{"this is a fake imooc.com"}
	//r=mock.Retrievers{"this is a fake imooc.com"}
	inspect(r)
	r=&real.Retriever{UserAgent:"Mozilla/5.0",TimeOut:time.Minute}
   //fmt.Printf("%T %v\n",r,r) 第一种打印方式
	inspect(r)
	//fmt.Println(download(r))
	//fmt.Println(download(r))
//第三种打印方式
      realRetriever := r.(*real.Retriever)
      fmt.Println(realRetriever.TimeOut)
	if mockRetriever,ok:=r.(mock.Retrievers);ok{
		fmt.Println(mockRetriever.Contentst)
	}else{
		fmt.Println("not a mock retriever")
	}
}

   接口变量里面有:实现者的类型、实现者的值(或者是实现者的指针指向实现者)
   接口变量自带指针,接口变量统一采用值传递,几乎不需要使用接口的指针
   指针接受者实现只能以指针方式使用,值接收者都可以 
   func的返回类型如果是interface的话不限制返回类型,但是可以在返回值时添加类型限制,比如 return head.(int )

   常用的接口:

   string:
        func (r *Retrievers)String()string{
        return  fmt.Sprintf(
            "Retriever:{Contents=%s}",r.Contentst)
}
 


   Read:实现的人读取文件给你的[]byte里面
   Write:写入到文件里面 

函数式编程:
   函数是一等公民:参数,变量,返回值都可以是函数
   高阶函数:函数的参数也可以是函数
 

   func adder() func(int)int{
    sum:=0
    fmt.Println(sum)
    return func(v int) int {
        sum+=v
        return  sum
    }
}
func main() {
    a:=adder()
    fmt.Println("............")
    for i:=0;i<10;i++{
        fmt.Println(a(i))
    }
}

猜你喜欢

转载自blog.csdn.net/ligupeng7929/article/details/88312184