一、 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)
}