• 切片类型、map、字符串、指针、结构体、方法、


    一、切片类型

    切片类型:是由数组建立的一种方便灵活的且功能强大的包装,切片本身不拥有任何数据类型,他只是对现有数组的引用。

    即:指向了一个地址,本身不拥有数据。

    package main
    
    import "fmt"
    
    func main() {
        //切片定义的第一种方式,由数组切出来
        //var a [8]int=[8]int{1,2,3,4,5,6,7,8}
        ////只是对数组的引用
        //var b []int=a[2:6]
        //fmt.Println(b)
        //a[2]=30
        //fmt.Println(b)
        //b[1]=40
        //fmt.Println(b)
        //fmt.Println(a)
        ////原数组的修改会影响切片
        ////切片的修改也会影响底层数组
        //a[1]=20
        //fmt.Println(b)
        //更多用法,没有步长
        //var a [8]int=[8]int{1,2,3,4,5,6,7,8}
        //b:=a[:4]
        //fmt.Println(b)
        //第二种方式,直接定义
        //切片空值是?nil类型
        //var a []int
        //if a==nil{
        //    fmt.Println("我是空的")
        //}
        //a[0]=10
        //fmt.Println(a)
        //定义并初始化,第一个参数是类型,第二个参数是切片的长度,第三个参数是底层数组长度,也就是切片的容量
        //var a []int=make([]int,3)
        //fmt.Println(a)
        //切片的长度和容量(len     cap:容量)
        //切片的长度就是它所包含的元素个数。
        //切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
        //var a [8]int=[8]int{1,2,3,4,5,6,7,8}
        //var b []int=a[2:6]
        //fmt.Println(len(b))
        //fmt.Println(cap(b))
        //var a []int=make([]int,3,4)
        //fmt.Println(a)
        //fmt.Println(len(a))
        //fmt.Println(cap(a))
    
        //切片追加值(即给切片赋值)
        //var a [8]int=[8]int{1,2,3,4,5,6,7,8}
        //var b []int=a[2:6]
        //fmt.Println(len(b))  //4
        //fmt.Println(cap(b))  //6
        ////内置函数append,append函数的返回值也为切片
        //b=append(b,555)
        //b=append(b,666)
        //追加两个值之后,容量为6,长度为6
        //底层数组a的相应位置数据也被修改了
        //fmt.Println(b)
        //fmt.Println(len(b))
        //fmt.Println(cap(b))
        //b[0]=999
        //fmt.Println(a)  //a[2]变为999
        //容量满了再继续追加
        //b=append(b,777)
        //fmt.Println(b)
        //长度为7
        //fmt.Println(len(b))
        //切片容量翻倍为12
        //fmt.Println(cap(b))
        //当切片超出底层数组长度时,再进行追加会重新创建一个数组,修改切片中的值不会影响原数组中的值
        //b[0]=999
        //fmt.Println(b)
        //fmt.Println(a)
        //var b =make([]int,3,4)
        //fmt.Println(b)  //[0,0,0]
        //b=append(b,4)
        //fmt.Println(b)  //[0,0,0,4]
        //fmt.Println(len(b))  //4
        //fmt.Println(cap(b))  //4
        //b=append(b,5)
        //fmt.Println(len(b))  //5
        //fmt.Println(cap(b))  //8
        //切片的修改
        //var b =make([]int,3,4)
        //b[0]=999
        //fmt.Println(b)
        //var b =make([]int,4,4)
        //fmt.Println(len(b))
        //fmt.Println(cap(b))
        //切片的函数传递
        //var b =make([]int,3,4)
        //test(b)
        //在函数中修改之后原b切片的值也会改变,即切片是引用传递
        //fmt.Println(b)
        //切片的数据结构表示
        //type slice struct {
        //    Length        int
        //    Capacity      int
        //    ZerothElement *byte
        //}
        //多维切片
        //var a [][]string=make([][]string,2,3)
        //fmt.Println(a[0])  //[]为空切片,只初始化了外层切片
        //a[0]=make([]string,2,3)  //为内层切片初始化
        //if a[0]==nil{
        //    fmt.Println("xxxx")
        //}
        //切片初始化的方法
        //var a []int=[]int{1,2,3}
        //fmt.Println(a)
        //fmt.Println(len(a))
        //fmt.Println(cap(a))
        //多维切片初始化
        //var a [][]string=[][]string{{"1","2"},{"3","4"}}
        //fmt.Println(a)
        //fmt.Println(len(a))
        //fmt.Println(cap(a))
        //a[0][1]="999"
        //fmt.Println(a)
        //a[1][0]="999"
        //var a []int=[]int{1,2}
        //fmt.Println(a)
        //a=append(a,3)
        //fmt.Println(len(a))
        //fmt.Println(cap(a))
        //a[2]=99
        //a[3]=888
        //fmt.Println(a)
        //copy函数
        var a =make([]int,3,10000)
        //底层数组很大,耗费内存
        a[1]=99
        a[2]=888
        fmt.Println(a)
    
        //var b =make([]int,4,4)
        var b =make([]int,2,4)
        fmt.Println(b)
        //将a copy 到另一个切片上去
        copy(b,a)
        fmt.Println(b)
    }
    
    func test(b []int)  {
        b[0]=999
        fmt.Println(b)
    }
    切片

    可变长参数:

    package main
    //可变长参数
    import "fmt"
    
    //可变长参数
    
    func main() {
        //var a =[]int{1,2,4,}
        //test1(1,2,3,4)
        //相当于打散了
        //test1(a...)
        //veggies := []string{"potatoes", "tomatoes", "brinjal"}
        //fruits := []string{"oranges", "apples"}
        //food := append(veggies, fruits...)
        //fmt.Println("food:",food)
    
        //循环多维切片
        pls := [][]string {
            {"C", "C++"},
            {"JavaScript"},
            {"Go", "Rust"},
        }
        fmt.Println(pls)
        for _,v:=range pls {
            for _,v1:=range v{
                fmt.Println(v1)
            }
        }
    
    }
    
    func test1(a ...int)  {
        fmt.Println(a)
        fmt.Printf("%T",a)
    
    }
    可变长参数

    二、map

    map:在Go中将键(key)值(value)关联起来的内置类型,通过相应的键来获取相应的值。

    map中放函数和用map实现set练习:

    package main
    
    //回顾
    
    //func main() {
    
        //指针数组和数组指针
        //数组里面放指针   指向数组的指针
        //
    
        //a:=10
        //b:=20
        ////数组里面放指针
        //c:=[2]*int{&a,&b}
        //fmt.Println(c)
        //指向数组的指针
        //a:=[2]int{1,2}
        //var b *[2]int
        //b=&a
        //fmt.Println(b)
    //}
    
    //-map内放函数
    //func main() {
    //    var m map[int]func(a int)int=make(map[int]func(a int)int)
    //    m[1]= func(a int) int {
    //
    //        return a
    //    }
    //    m[2]= func(a int) int {
    //        return a*a
    //    }
    //    m[3]= func(a int) int {
    //        return a*a*a
    //    }
    //
    //    fmt.Println(m[1](9))
    //    fmt.Println(m[2](9))
    //    fmt.Println(m[3](9))
    //}
    
    //-通过map实现set
    func main() {
        //集合
        //可以放值,如果重复了,放不进去
        //可以获取长度
        //判断一个值是否在集合内
        //把集合内所有元素打印出来
        //
        //var m map[string]bool=make(map[string]bool)
        //m["lqz"]=true
        //m["egon"]=true
        //
        //m["lqz"]=true
        //
        //fmt.Println(len(m))
        ////"aa"是否在集合内
        //if m["aa"]{
        //    fmt.Println("在里面")
        //}else {
        //    fmt.Println("不再")
        //}
        //for k,_:=range m{
        //    fmt.Println(k)
        //}
    
    
    }
    练习
    //maps
    package main
    
    import "fmt"
    
    func main() {
        //maps的定义
        //map的key值必须可hash
    
        //var a map[键值类型]value值类型
        //map的空值是nil类型
        //也是引用类型,在函数中修改原来的值也会被修改
        //var a map[int]string
        //fmt.Println(a)
        //if a==nil{
        //    fmt.Println("xxxx")
        //}
        //map的赋值跟取值
        //map的初始化
        //var a map[int]string=make(map[int]string)
        //fmt.Println(a)
        ////if a==nil{
        ////    fmt.Println("xxxxx")
        ////}
        //a[1]="100"
        //a[2]="888"
        //fmt.Println(a)
        //fmt.Println(a[1])
        ////取一个不存在的key值会?返回value值的空值的默认值(int为0,string为“”)
        ////fmt.Println(a[9])
        //var b map[int]int=make(map[int]int)
        //b[1]=100
        //fmt.Println(b)
        ////fmt.Println(b[9])
        //if v,ok:=a[9];ok{
        //    fmt.Println("=-====",v)
        //}else {
        //    fmt.Println("该值不存在")
        //}
        //v,ok:=a[1]
        //fmt.Println(v)
        //fmt.Println(ok)
        //定义和初始化的第二种方式
        //var a =map[int]string{1:"10",2:"100"}
        ////a[1]
        //fmt.Println(a[1])
        //字典删除元素,内置函数
        //var a =map[int]string{1:"10",2:"100"}
        ////delete(a,2)
        //delete(a,3)
        //fmt.Println(a)
    
        //map长度
        //var a =map[int]string{1:"10",2:"100"}
        //delete(a,1)
        //a[10]="999"
        //fmt.Println(len(a))
        //Map 是引用类型
    
        //var a =map[int]string{1:"10",2:"100"}
        //test4(a)
        //fmt.Println(a)
        //Map 的相等性
    
        //map1 := map[string]int{
        //    "one": 1,
        //    "two": 2,
        //}
        //
        //map2 := map1
    
        //if map1 == map2 {  //报错
        //}
    
        //map循环出所有元素
        ////map是无序的
        //for k,v:=range a{
        //    fmt.Println(k)
        //    fmt.Println(v)
        //}
    
    
    
        //补充:切片删除元素
        //var a =[]int{1,2,3,4,5,6}
        //a=append(a[0:2],a[3:]...)
        //fmt.Println(a)
    
    }
    
    func test4(a map[int]string)  {
        a[1]="888"
        fmt.Println(a)
    
    }
    
    //把map做成有序作业
    map

    三、字符串

    字符串:

    package main
    
    import (
        "fmt"
        "unicode/utf8"
    )
    
    func main() {
    
        //name := "Hello World刘清政"
        //name:=""
        //字符串长度,len统计字节数
        //在go中string类型都是utf-8编码
        //fmt.Println(len(name))
        //fmt.Println(utf8.RuneCountInString(name))
        //unicode是一个字符编码对照表
        //循环
        //字符串是个只读切片
        //name := "name刘"
        //循环的是字节
        //for i:=0;i<len(name);i++{
        //    fmt.Println(string(name[i]))
        //    fmt.Printf("%T",name[i])
        //    fmt.Println()
        //}
    
        //循环的是字符
        //for _,v:=range name{
        //    fmt.Println(string(v))
        //    fmt.Printf("%T",v)
        //    fmt.Println()
        //}
    
        //name := "name刘"
        //name[0]=99
        //fmt.Println(name[0])
        //fmt.Println(string(name[0]))
    
        byteSlice := []byte{0x43, 0x61, 0x66, 0xC3, 0xA9}
        str := string(byteSlice)
        a:=len(str)
        b:=utf8.RuneCountInString(str)
        fmt.Println(b)
        fmt.Println(a)
        fmt.Println(str)
    
    }
    字符串

    四、指针

    指针:是一种存储变量内存地址的变量。

    //指针
    package main
    
    import "fmt"
    
    func main() {
        //&取地址符号
        //* 放在类型旁边,表示指向这个类型的指针
        //* 放在变量旁边,表示解引用(反解)
        //a:=10
        //b就是一个指针 指向int类型的指针
        //b:=&a
        //d:="sss"
        //var c *string=&d
        //var b *int =&a
        //fmt.Println(b)
        //fmt.Println(*b)
        //c:=&b
        //var c **int=&b
        //fmt.Println(*(*c))
        //指针的零值(Zero Value),nil类型
        //var a *int
        //fmt.Println(a)
        //向函数传递指针参数
        //a:=10
        ////b:=&a
        ////test6(b)
        ////fmt.Println(a)
        //test7(a)
        //fmt.Println(a)
        //func test6(b *int)  {
        //    //*b 就是 a  a++
        //    *b++
        //原来a的值也会被修改
        //    fmt.Println(*b)
        //}
        //func test7(b int)  {
        //    b++
        //原来a的值不会改变
        //    fmt.Println(b)
    
        //不要向函数传递数组的指针,而应该使用切片
        //var a [100]int
        ////test9(&a)
        ////fmt.Println(a)
        //test10(a[:])
        //fmt.Println(a)
        //Go 不支持指针运算
    
    }
    // 若向函数传递指针则数组指针的长度写死了,受众范围小
    func test9(a *[4]int)  {
        (*a)[0]=999
        //底层数组也会受到影响
        fmt.Println(a)
    }
    func test10(a []int)  {
        //使用切片同样可以修改底层数组
        a[0]=999
        fmt.Println(a)
    
    }
    //}
    指针相关用法及特点

    五、结构体

    package main
    
    //结构体:是一系列属性的集合
    //定义一个人结构体
    
    //type关键字 结构体名字 struct{}
    //type Person struct {
    //    name string
    //    sex ,age int
    //
    //}
    //匿名字段表示字段没有名字
    //type Person struct {
    //    string
    //    int
    //}
    //嵌套结构体
    //type Person struct {
    //    name string
    //    sex ,age int
    //    hobby Hobby
    //
    //}
    //type Hobby struct {
    //    id int
    //    name string
    //}
    //结构体嵌套+匿名字段
    type Person struct {
        name string
        sex ,age int
        Hobby
    
    }
    type Hobby struct {
        id int
        //hobbyname string
        name string
    }
    
    func main() {
        //person  :=Person{}
        //定义没有初始化
        //结构体是值类型
        //var person Person
        //var person Person=Person{name:"lqz"}
        //var person Person=Person{"lqz",1,19}
        ////person.name="lqz"
        //fmt.Println(person.name)
        //匿名结构体
        //age:=10
        //name:="lqz"
        //
        //a:=struct {
        //    name string
        //    age int
        //}{"lqz",19}
        //fmt.Printf(a.name)
    
        //结构体的零值
        //结构体指针
        //p:=Person{name:"lqz"}
        ////pPoint:=&p
        //var pPoint *Person=&p
        ////fmt.Println(pPoint)
        ////fmt.Println((*pPoint).name)
        //可以直接指针.变量名来获取
        //fmt.Println(pPoint.name)
        //匿名字段(用作变量提升)
        //p:=Person{"lqz",19}
        //用类型名来代替变量名
        //p:=Person{string:"lqz",int:19}
        //fmt.Println(p.string)
    
        //嵌套结构体
        //p:=Person{name:"lqz",hobby:Hobby{10,"篮球"}}
        //p:=Person{name:"lqz",hobby:Hobby{id:10,name:"篮球"}}
        //p.hobby.id=101
        //
        //fmt.Println(p.hobby.name)
        //结构体嵌套加匿名字段
        //p:=Person{name:"lqz",Hobby:Hobby{10,"篮球"}}
        ////取p中的hobbyname
        //fmt.Println(p.Hobby.hobbyname)
        //fmt.Println(p.hobbyname)
        //变量提升过程中如果有重名的,就不提升了
        //p:=Person{name:"lqz",Hobby:Hobby{10,"篮球"}}
        //fmt.Println(p.Hobby.name)
        //fmt.Println(p.name)
        //结构体相等性
    
    }
    结构体相关用法

    六、方法

    方法:方法其实就是一个函数,在func关键字和方法名之间加入了一个特殊的接收器类型,接收器可以是结构体类型,或者非结构体类型,接收器是可以在方法的内部访问的

    package main
    
    import "fmt"
    
    //方法     其实就是一个函数
    
    type Person struct {
        name string
        age int
        sex int
    }
    
    
    //语法
    //func (a Person) getName()  {
    //
    //}
    //方法给对象用
    //给Person结构体加一个打印名字的方法
    func (a Person)printName()  {
        fmt.Println(a.name)
    }
    //func (a Person)changeName(name string)  {
    //    a.name=name
    //    fmt.Println(a)
    //}
    func (a *Person)changeName(name string)  {
        a.name=name
        fmt.Println(a)
    }
    //func printName(a Person)  {
    //    fmt.Println(a.name)
    //}
    //func printName(a *Person)  {
    //    fmt.Println(a.name)
    //}
    func main() {
        //var p *Person=&Person{name:"lqz"}
        //这种也可以,go给你处理了
        //var p Person=Person{name:"lqz"}
        //p.changeName("egon")
        值类型的接收器,不会影响原p的值
        //fmt.Println(p)
        //p.printName()
        //为什么我们已经有函数了还需要方法呢
        //执行函数
        //printName(p)
        //printName(&p)
    
        //指针接收器与值接收器
        //func (值)changeName(name string):在内部修改值,不会影响外部的值
        //func (指针)changeName(name string):在内部修改值,会影响外部的值
    
        //那么什么时候使用指针接收器,什么时候使用值接收器
        //想修改原值,就用指针接收器
        //匿名字段的方法
    
    
    }
    方法

    非结构体上的方法:

    package main
    
    import "fmt"
    
    //在非结构体上的方法
    
    
    //重命名
    type MyInt int
    
    
    func (i *MyInt)add()  {
        (*i)++
        fmt.Println(*i)
    }
    
    func main() {
        var a MyInt=10
        a.add()
        fmt.Println(a)
    }
    非结构体上的方法

    在方法中使用值接收器 与 在函数中使用值参数
    在方法中使用指针接收器 与 在函数中使用指针参数

    package main
    
    import "fmt"
    
    //在方法中使用值接收器 与 在函数中使用值参数
    //在方法中使用指针接收器 与 在函数中使用指针参数
    
    
    
    type Person2 struct {
        name string
        age int
        sex int
    }
    //方法中使用值接收器
    func (a Person2)printName()  {
        fmt.Println(a.name)
    
    }
    //方法中使用指针接收器
    func (a *Person2)printName2()  {
        fmt.Println(a.name)
    }
    //函数中使用值参数
    func printName(a Person2)  {
        fmt.Println(a.name)
    }
    //在函数中使用指针参数
    func printName2(a *Person2)  {
        fmt.Println(a.name)
    }
    
    func main() {
        //p:=&Person2{name:"lqz"}
        //调用值接收器
        //p.printName()
        //调用指针接收器
        //p.printName2()
        //调用值函数
        //printName(p)
        //调用指针函数
        //printName2(&p)
        //方法中:
        //不管是指针接收器还是值接收器,都可以使用值来调用
        //不管是指针接收器还是值接收器,都可以使用指针来调用
        //函数中:
        //是什么参数,就得传什么参数
    
    
    
    
    
    
    
    }
    值接收器与指针接收器

    七、接口

    接口:在面向对象中,接口一般定义一个对象的行为,接口只是制定了对象应该做什么,至于如何实现这个行为,则由对象本身去决定。

  • 相关阅读:
    win10打开相机提示我们找不到你的相机
    Potplay视频播放画面扭曲
    SIFT特征匹配算法介绍
    SelectiveSearchCodeIJCV遇到First two input arguments should have the same 2D dimension
    mybatis逆向工程mvn插件
    ssm配置
    springmvc配置
    MyBatis如何禁用掉一级缓存
    Mybatis中#{}和${}的区别
    Java demo之IO
  • 原文地址:https://www.cnblogs.com/yangjiaoshou/p/12026231.html
Copyright © 2020-2023  润新知