go语言学习笔记(4)--容器与字符串的基本概念

一、 Slice(切片)

package main

import (
   "fmt"
)

//切片,slice
func main() {
   arr := [...]int{1,2,3,4,5,6,7,8}
   s := arr[2:6] //下标2到下哦5取出来给s
  
fmt.Print("arr 2 .. 6",s)
   fmt.Print("arr :" ,arr[:]) // 这个arr[:]是个视图。修改的话回改变到,slice本身没有数据,改变回影响底层

  
fmt.Println("arr :2", arr[:2])
   fmt.Println("arr 2:", arr[2:])
   s2 := s[3:5] // 3456
  
fmt.Println(s2) //虽然没有,但是还是有值,切片只是改变出事下标的位置,然后数那么多个就行。

   //这里讲有一个重点:slice切片
   /***slice结构如下,用c语言的结构体表示
   struct slice{
   ptr //只想初始位置
   len //slice的长度,如果访问下标超过长度就会报错
   cap //这个是从起始下标一直数到结尾,
   }
   如上栗子, arr{1,2,3,4,5,6,7}
   a[2:6]
   那么这个slice 的ptr是2,len是6-2,cap就是arr.lenth() - ptr所有元素,
   在操作的时候,如s2 = s[3:5] 这里的值只要不超过cap,就不会越界
   **slice可以向后扩展,但是不能向前扩展。
    */
    //对上面
    //可以通过len(s1) ,cap(s1)查看相应的值,还有需要说明的对于数组可以使用%v来作为值得格式控制
   
fmt.Printf("%v,%d,%d",s,len(s),cap(s))

    //slice添加元素
  
s3 := append(s, 10)
   s4 := append(s3, 55) //append,如果slice在原数组得范围内,对原数组进行修改,、
                        // 如果超过了就把原来得数组拷过去形成新得数组
  
fmt.Println(s3,s4)
   //多说一句,这里得数组拷过去,原来得数组就会被垃圾回收机制回收掉。没错,go语言具有垃圾回收机制
   //append可能造成slice内部得3个值都改变,所以对这个append需要使用一个slice来接收如上,s3与s4都是slice

   //跳到函数讲解,
  
opslice()
}

func opslice(){
   //创建slice,数组方式就先不说了
   //1
  
var s []int // zero value for slice is nil .这个时候slice s 就是一个空 nil
  
s = append(s, 1)//增加一个元素1
  
fmt.Println(s)

   s1 := []int{1,2,3,4,5} //这是一个slice
  
fmt.Println(s1)

   s2 := make([]int,16) //创建一个长度为16的slice,知道长度,不知道值 //全是0

  
s3 := make([]int,2,5) //类型,长度,cap ,这里的3个参数 //全是0
  
fmt.Println(s1,s2,s3)

   //slice的复制
  
s3[0] = 1
   copy(s2,s3)//把s3 复制给 s2
  
fmt.Println(s2,s3) //复制只是按位复制,不是把整个样子复制过去

   //slice删除 我要删掉第3个元素
  
s1 = append(s1[:3],s1[4:]...)//第二的参数4开头所有元素表示法
  
fmt.Println(s1)

   //拿到头尾就不讲了,。。。取值再删除
}

二、 Map

package main

import "fmt"

//map
func main() {
   //map的定义
   //1
  
m := map[string]string{
      "a":"a",
      "b":"b" ,
      "c":"c",//键与值的对应关系,注意最后的这个逗号
  
}
   s := m["a"] //取得相应的值
  
fmt.Println(s)

   //2
  
m2 := make(map[string]string) //定义一个空的map
  
var m3 map[string]string //空的map
  
fmt.Println(m2,m3) //这样的话,m2 = empty map ;m3 = nil

   //map的遍历
  
for k,v := range m  {
      //k := range m // 这样只拿k
      //_,v := range m //这样就只拿值 很少有只拿值得情况
      /**
      联想,前面还想也有类似得用法,是在range第二次出现的时候,数组下标与数组值得取得
       */
     
fmt.Println(k,v) //这个map是一个hashmap
  
}

   //取值小demo
  
s1 := m["a"]
   s2 := m["sdfasdf"] //明显不存在

   //当然还能这样
  
s3,is := m["adfaf"]
   fmt.Println(s1,s2) //此时输出的s2 ,,官方说法,这是一个zero value
  
fmt.Println(s3,is) //如果是一个不存在的键,会是zero value,is值也会是false
   /***
   知识点,什么是zero value -->字面意思 就是0 或者空串等,理解下
    */

    //那么讲下用法
   
if s4,ok := m["b"];ok{
      fmt.Println(s4) //这样的情况
   
}else {
      fmt.Println("没有这个键")
    }

    //map 删除元素
   
delete(m,"c") // 直接删除,

    /***
    知识点,什么类型可以作为key呢?
    ''''java中要作为key,必须实现hashcode和equals,
    go语言中,
    首先要能够判断是否相等,
    其次除了slice,map,function的内建类型都可以作为key
    还有就是结构体,不包含上面这几个字段,也可以作为key,编译的时候就会检查
     */
}

三、 字符串讲解。

package main

import (
   "fmt"
   "unicode/utf8"
)

//字符串讲解
func main() {
   var s string = "yes,我爱go语言!"
  
fmt.Println(len(s)) //结果是21,一个英文一个字节,一个中文3个字节,采用utf-8的编码,这是一种可变长度的编码方方式

  
for i,ch := range []byte(s)  {
      fmt.Printf("(%d,%X)",i,ch)//这样是解码之后的,就是才用utf-8的,%X表示以16位输出
  
}
   fmt.Println()
   for i,ch := range s  {
      fmt.Printf("(%d,%X)",i,ch)//这样是解码之后的,是unicode,不可变,
  
}
   fmt.Println()
   for i,ch := range []rune(s)  {
      fmt.Printf("(%d,%X)",i,ch)//这样是解码之后的,同意为rune类型,支持国际化,全是int32
  
}
   fmt.Println()

   //接下来讲几个方法
  
utf8.RuneCountInString(s) //计算长度,通过utf-8计算的

  
ch,size := utf8.DecodeRune([]byte(s)[7:]) //通过utf-8解码 //这里可以返回两个值,一个是解码的每一个字符,一个是这个字符站的字节数
   //这是将一个字节数组拿去解码,按照utf-8解码,出错同意返回
,1
  
fmt.Printf("%c,%d",ch,size)


}

猜你喜欢

转载自www.cnblogs.com/luohuayu/p/9168917.html