go的"引用传递"

1.链表改变头指针和返回投指针

package main

import "fmt"

type Node struct {
    num  int
    next *Node
}

func main() {
    n := 0
    fmt.Scan(&n)
    head := &Node{-1, nil}
    tmp := head
    for i := 1; i <= n; i++ {
        tmp.next = &Node{i, nil}
        tmp = tmp.next
    }
    head = head.next
    reverse(head)
    //head = reverse1(head)
    Print(head)
}

func reverse(head *Node) {
    first := head
    second := head.next
    head.next = nil
    for second != nil {
        tmp := second
        second = second.next
        tmp.next = first
        first = tmp
    }
    head = first
}
func reverse1(head *Node) *Node {
    first := head
    second := head.next
    head.next = nil
    for second != nil {
        tmp := second
        second = second.next
        tmp.next = first
        first = tmp
    }
    head = first
    return head
}
func Print(head *Node) {
    tmp := head
    for tmp != nil {
        fmt.Printf("%d ", tmp.num)
        tmp = tmp.next
    }
    fmt.Println()
}

上面的区别主要在于我是直接改编原头指针的指向还是返回一个新指针后在main函数中改变指向

通过编译分析发现head首先就是main函数中的地址,通过赋值之后指向最后一个元素,但是函数返回之后还是指向第一个元素,也就是说,**在函数内部改变指针的指向是没有用的**

这么说go的指针是值传递,不是引用传递?

事实上说,go语言是没有引用传递的,go语言之所以可以达到引用传递的效果,实际上是这些数据结构底层的指针指向同一片内存地址,从而达到看似引用传递的效果.

所以说在函数内部不能修改指针的指向?

是的,指针本质上就是一个内存地址,也就是一个8位或者4位的二进制数,这个地址在函数传递的时侯其实也是传递的一份副本,只不过指向同一片内存,对这个内存的修改对其他函数也可见.例如,如果切片在函数中发送了阔容,函数外的切片孩是不会变化的

package main

import "fmt"

func main() {
    s := make([]int, 1, 3)
    //s := make([]int, 1, 20)
    fmt.Printf("cap:%d len:%d arrs:%p \n", cap(s), len(s), &s[0])
    extendSlice(s)
    fmt.Printf("cap:%d len:%d arrs:%p \n", cap(s), len(s), &s[0])
}
func extendSlice(s []int) {
    fmt.Printf("cap:%d len:%d arrs:%p \n", cap(s), len(s), &s[0])
    for i := 0; i < 7; i++ {
        s = append(s, i)
    }
    fmt.Printf("cap:%d len:%d arrs:%p \n", cap(s), len(s), &s[0])
}
//stdin
//cap:3 len:1 arrs:0xc00001c198 
//cap:3 len:1 arrs:0xc00001c198 
//cap:12 len:8 arrs:0xc000028240 
//cap:3 len:1 arrs:0xc00001c198 

既然说到这里了,go语言还有个unsafe.Pointer,这个有什么区别?

首先看看unsafe.Pointer的结构
 

//这里就不放官方解释了,感兴趣的去看源码
//大概意思是unsafe.Pointer可以表示任意类型的指针,也可以转成任意类型,并绕过类型检察读写其内存值
type Pointer *ArbitraryType

// ArbitraryType is here for the purposes of documentation only and is not actually
// part of the unsafe package. It represents the type of an arbitrary Go expression.
//大概意思是这个结构体属于任意类型
type ArbitraryType int

unsafe.Pointer的作用主要就是跳过类型检测修改一些数据,但是在实际的开发中并不建议这样做,因为不好维护而且容易出bug

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值