zoukankan      html  css  js  c++  java
  • Go new函数 例子解析答疑

    package main
    
    import "fmt"
    
    func main() {
    	p1 :=new(int)
    	*p1 =1
    	fmt.Println("p1",p1)
    	fmt.Println("*p1",*p1)
    	fmt.Println("&p1",&p1)
    
    	s1 := new([]int)
    	s2 := []*int{}
    	s3 := []int{1,2}
    
    	s2 =append(s2,p1)
    	fmt.Println("s1: ", s1)
    	fmt.Printf("s2:%v
    ", s2)
    	fmt.Printf("s2:%T
    ", s2)
    	fmt.Println("s3: ", s3)
    
    
    }
    

    输出

    p1 0xc00000a0d0
    *p1 1
    &p1 0xc000006028
    s1:  &[]
    s2:[0xc00000a0d0]
    s2:[]*int
    s3:  [1 2]
    

    问题一 s1,s2,s3的区别是什么?

    s1 将创建一个[]int类型的匿名变量,初始化为[]int类型的零值,然后返回变量地址,返回的指针类型为 *[]int 。

    s2 声明创建一个int指针类型的空切片。

    s3 声明创建一个int类型的切片,初始化字面量1,2。

    s1是指针地址,s2是存放指针地址的切片,s3就是一个切片。

    用new创建变量和普通变量声明语句方式创建变量没有什么区别,除了不需要声明一个临时变量的名字外,还可以在表达式中使用new(T)。new函数类似是一种语法糖,直接返回变量的地址,而不是一个新的基础概念。

    下面的两个newInt函数有着相同的行为:

    func newInt() *int {
        return new(int)
    }
    
    func newInt() *int {
        var dummy int
        return &dummy
    }
    

    每次调用new函数都是返回一个新的变量的地址,因此下面两个地址是不同的:

    p := new(int)
    q := new(int)
    fmt.Println(p == q) // "false"
    

    当然也可能有特殊情况:如果两个类型都是空的,也就是说类型的大小是0,例如struct{}[0]int,有可能有相同的地址。

    new函数使用常见相对比较少,因为对应结构体来说,可以直接使用字面量语法创建新变量的方法会更灵活。

    由于new只是一个预定义的函数,它并不是一个关键字,因此可以将new名字重新定义为别的类型。例如下面的例子:

    func delta(old, new int) int { return new - old}
    

    由于new被定义为int类型的变量名,因此在delete函数内部是无法使用内置的new函数的。

    问题二 s2如何才能像s3一样直接赋值?

    s2是int类型指针切片,直接存放int类型的指针地址就好

    问题三 s2赋完值之后如何才能打印出来值类型?

    参考:Go语言fmt.Sprintf、fmt.Printf(格式化输出)

    %T 	输出 Go 语言语法格式的类型和值
    
    fmt.Printf("s2:%T
    ", s2)
    

    输出

    s2:[]*int
    
  • 相关阅读:
    场景设计法
    判定表驱动分析方法
    错误推测法
    Ubuntu软件包管理命令全面集锦
    MySql模糊查询
    VC++ 列表控件的使用方法
    Java笔记原生数据类型【二】
    DEDECMS 关键字不能小于2个字节!
    Linux 使用yum install安装mysql登陆不上解决办法
    PHP数据学习-二维数组【3】
  • 原文地址:https://www.cnblogs.com/niuben/p/14429025.html
Copyright © 2011-2022 走看看