【go语言基础】-指针

符号:

  &:取地址符号

  *:取地址的值的符号

*(指针)与&(地址)

 

定义int的指针

	var ip *int //这个变量里面就只能保存地址类型这种值
	ip = &a

	fmt.Println(a)
	fmt.Println(ip)

	//如果要修改指针指向的变量的值,用法也比较特殊
	*ip = 30

  

定义数组指针

	//指针还可以指向数组 指向数组的指针 数组是值类型
	arr := [3]int{1, 2, 3}
	var ip *[3]int = &arr

	//指针数组
	var ptrs [3]*int //创建能够存放三个指针变量的数组
	//很多时候都是函数参数的时候指明的类型
	//指针的默认值是nil
	if ip != nil {
	
	}

 

package main

import "fmt"

func swap(a *int, b *int) {
	//用于交换a和b
	c := *a
	*a = *b
	*b = c
}
func main() {
	//什么指针,我们提一个问题
	a := 10
	b := 20
	//swap(a, b)
	fmt.Println(a, b)
	//为什么交换不成功, 这个函数运行完成以后 我想要把a和b的值变掉
	//指针 - 对于内存来说,每一个字节其实都是有地址-通过16进制打印出来
	fmt.Printf("%p\n", &a) //变量有地址
	//现在有一种特殊的变量类型,这个变量只能保存地址值
	var ip *int //这个变量里面就只能保存地址类型这种值
	ip = &a

	fmt.Println(a)
	fmt.Println(ip)

	//如果要修改指针指向的变量的值,用法也比较特殊
	*ip = 30
	fmt.Println(a)
	fmt.Println(*ip)

	fmt.Println(&a)
	fmt.Println(ip)

	////如何定义指针变量 如果修改指针变量指向的内存中的值。 通过指针去取值的时候不知道应该取多大的连续内存空间
	//fmt.Printf("ip所指向的内存空间地址是:%p, 内存中的值是: %d\n", i p, *ip)
	//swap(&a, &b)
	//fmt.Println(a, b)
	////还不足以说服大家
	////但是go中数组是值传递 数组中有100万个值, 对于这种一般我们都采用切片来传递
	////在python中list和dict这种传递都是引用传递
	//
	//指针还可以指向数组 指向数组的指针 数组是值类型
	arr := [3]int{1, 2, 3}
	var ip *[3]int = &arr

	//指针数组
	var ptrs [3]*int //创建能够存放三个指针变量的数组
	//很多时候都是函数参数的时候指明的类型
	//指针的默认值是nil
	if ip != nil {

	}
	////像python和java这种语言都是极力的屏蔽指针, c/c++ 都提供了指针 指针本身是很强大
	////c和c++中指针的功能很强大 指针的转换 指针的偏移 指针的运算
	////go语言没有屏蔽指针,但是go语言在指针上做了大量的限制,安全性高很多,相比较 c和c++灵活性就降低了
	////指针变量中涉及到两个符号 & 和 *
	//
	////make, new, nil
}

 

默认值 int byte rune float bool string 这些类型都有默认值
指针, 切片 map, 接口这些默认值是nil 理解为none

new和make函数:

正常定义一个空的变量,不会分配内存空间,使用new函数定义后,会申请一个内存空间,这里的内存中的值全部设置为0

    //对于指针来说或者说其他的默认值是0的情况来说 如何一开始申明的时候就分配内存
    var p *int = new(int) //go的编译器就知道先申请一个内存空间,这里的内存中的值全部设置为0
    *p = 10

 除了new函数可以申请内存以外 还有一个函数就是make,更加常用的是make函数, make函数一般用于切片 map

new函数返回的是这个值的地址 指针 make函数返回的是指定类型的实例

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    //make和new函数
    //new函数用法
    //var p *int //申明了一个变量p 但是变量没有初始值 没有内存
    //*p = 10
    //默认值 int byte rune float bool string 这些类型都有默认值
    //指针, 切片 map, 接口这些默认值是nil 理解为none
    var a int
    a = 10
    fmt.Println(a)

    //对于指针来说或者说其他的默认值是0的情况来说 如何一开始申明的时候就分配内存
    var p *int = new(int) //go的编译器就知道先申请一个内存空间,这里的内存中的值全部设置为0
    *p = 10

    //int使用make就不行
    //除了new函数可以申请内存以外 还有一个函数就是make,更加常用的是make函数, make函数一般用于切片 map
    var info map[string]string = make(map[string]string)
    info["c"] = "bobby"

    //new函数返回的是这个值的地址 指针 make函数返回的是指定类型的实例
    //nil的一些细节
    var info2 map[string]string
    if info2 == nil {
        fmt.Println("map的默认值是 nil")
    }

    var slice []string
    if slice == nil {
        fmt.Println("slice的默认值是 nil")
    }

    var err error
    if err == nil {
        fmt.Println("error的默认值是 nil")
    }

    //python中的None和go语言中的nil类型不一样,None是全局唯一的
    //go语言中 nil是唯一可以用来表示部分类型的零值的标识符, 它可以代表许多不同内存布局的值
    fmt.Println(unsafe.Sizeof(slice), unsafe.Sizeof(info2))

}

 

posted @ 2022-06-11 18:25  wanghhhh  阅读(43)  评论(0)    收藏  举报