• golang (10 语法)


    1.go for循环,其中for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环(map就是字典)

    for key, value := range oldMap {
        **
    } 


    2.beego中的var定义
    var (
        NotPV []string = []string{"css", "js", "class", "gif", "jpg", "jpeg", "png", "bmp", "ico", "rss", "xml", "swf"}
    )

    var不仅声明了变量,并且会初始化变量,同时()

    格式:var v_name v_type
    //类型相同多个变量, 非全局变量
    var vname1, vname2, vname3 type
    vname1, vname2, vname3 = v1, v2, v3
    
    var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要显示声明类型,自动推断
    
    vname1, vname2, vname3 := v1, v2, v3 //出现在:=左侧的变量不应该是已经被声明过的,否则会导致编译错误
    
    
    // 这种因式分解关键字的写法一般用于声明全局变量
    var (
        vname1 v_type1
        vname2 v_type2
    )

     2.type 类型的定义

    //A basic Person struct,定义一个struct类型
    type Person struct {
        name string
        age int
    }
    
    //Some slices of ints, floats and Persons,定义slice类型,名称,slice的类型
    type IntSlice []int
    type Float32Slice []float32
    type PersonSlice []Person
    
    //定义接口类型 type,接口中只有方法,没有属性
    type MaxInterface interface {
        // Len is the number of elements in the collection.
        Len() int
        //Get returns the element with index i in the collection
        Get(i int) interface{}
        //Bigger returns whether the element at index i is bigger that the j one
        Bigger(i, j int) bool
    }
    
    3.go中值的传递和引入传递

    1. string int [] 都是值拷贝(值拷贝传递)
    2. slice的传递是引入传递,影响本身的slice的值(引用传递)
    3. 指针传递(穿的是指针,也不是引用传递)
    4.defer用法
    1. 执行顺序是在return后,或者函数执行完后才执行。多个defer的执行顺序是按照调用顺序的相反顺序逐个执行
    2. 即使函数发生错误也能执行
    3. 支持匿名函数的调用
    4. 常用于资源清理、文件关闭、解锁以及记录时间等操作

    func main() {
    for i := 0; i < 3; i++ {
    defer fmt.Println(i)
    }

    fmt.Println("888")
    }

    //结果是888、2、1、0

    defer在闭包中:
    func main() {
    for i := 0; i < 3; i++ {
    defer func(i int) {
    fmt.Println(i)
    }(i)
    }
    }
    //2、1、0(闭包的逻辑跟js是一样的)
    func main() {
    for i := 0; i < 3; i++ {
    defer func() {
    fmt.Println(i)
    }()
    }
    }
    //3、3、3,这里为什么是3,而不是2呢。因为当循环到 i = 3时,这个循环才结束,从而这个函数结束,因此defer拿到的是3


    4.make用法

    make用于内建类型(map、slice 和channel)的内存分配。new用于各种类型的内存分配。make只能创建slice、map和channel,并且返回一个有初始值(非零)的T类型(引用),而不是*T。本质来讲,导致这三个内建类型有所不同的原因是:引用在使用前必须被初始化。例如,一个slice,是一个包含指向数据(内部array)的指针、长度和容量的三项描述符;在这些项目被初始化之前,slice为nil。对于slice、map和channel来说,make初始化了内部的数据结构,填充适当的值。make返回初始化后的(非零)值。
    var map1 map[string]string = make(map[string]string)   //创建map
    var slice = make([]string,10,20) //直接创建slice
    var s1[]int //创建slice
    a := [10]int
    s2 := a[9] //生成slice
    for i := range ss {
            ss[i] += 10
            fmt.Println(i);    i是索引的值0,1
        }

    5.数组
    rb := [12]int{22,44,566}                 //1.[leng]type{content}   用{}做结构体
    var tt = [12]int{55,44,566}        
    rb2 := [12]int(tt) //2.用()来引入别的数组

    //rb2 := []int(tt) 这样会报错,因为内存大小长度不一致
     6.go的指针和变量的存放位置

    编译器会自动选择在栈上还是在堆上分配局部变量的存储空间,但可能令人惊讶的是,这个选择并不是由用var还是new声明变量的方式决定的。

    var global *int
    
    func f() {
        var x int
        x = 1
        global = &x
    }
    
    func g() {
        y := new(int)
        *y = 1
    }


    f函数里的x变量必须在堆上分配,因为它在函数退出后依然可以通过包一级的global变量找到,虽然它是在函数内部定义的;用Go语言的术语说,这个x局部变量从函数f中逃逸了。相反,当g函数返回时,变量*y将是不可达的,也就是说可以马上被回收的。因此,*y并没有从函数g中逃逸,编译器可以选择在栈上分配*y的存储空间(译注:也可以选择在堆上分配,然后由Go语言的GC回收这个变量的内存空间),虽然这里用的是new方式。其实在任何时候,你并不需为了编写正确的代码而要考虑变量的逃逸行为,要记住的是,逃逸的变量需要额外分配内存,同时对性能的优化可能会产生细微的影响。

    Go语言的自动垃圾收集器对编写正确的代码是一个巨大的帮助,但也并不是说你完全不用考虑内存了。你虽然不需要显式地分配和释放内存,但是要编写高效的程序你依然需要了解变量的生命周期。例如,如果将指向短生命周期对象的指针保存到具有长生命周期的对象中,特别是保存到全局变量时,会阻止对短生命周期对象的垃圾回收(从而可能影响程序的性能)。




  • 相关阅读:
    通过JDBC连接HiveServer2
    HDP-2.6.1安装
    VMWare虚拟机NAT模式静态IP联网配置
    基于ansj_seg和nlp-lang的简单nlp工具类
    修改ES使用root用户运行
    使用MapReduce将HDFS数据导入到HBase(三)
    HBase表操作
    使用SpringMVC解决Ajax跨域问题
    SpringBoot之Web开发——webjars&静态资源映射规则
    thymeleaf+springboot找不到html,只返回了字符串
  • 原文地址:https://www.cnblogs.com/jay--zhang/p/6731736.html
Copyright © 2020-2023  润新知