设为首页 加入收藏

TOP

Go语言【数据结构】指针知多少?(一)
2019-09-24 11:16:12 】 浏览:105
Tags:语言 数据结构 指针 多少

指针

  本章围绕字符串、数字、数组、切片、map、channel、结构体与指针赋值及函数传参的应用剖析

 

字符串

字符串本身也是StringHeader的结构体,包含Data指针与字符串长度,如下

type StringHeader struct {
    Data uintptr
    Len  int
}

Data指向的内存地址不可更改,字符串赋值和传参只是拷贝了StringHeader中Data和Len的值

package main

import "fmt"

func main()  {
	str := "Hello World!"
	var data string
	data = str
	// 拷贝str中Data与Len
	fmt.Println(data)
	data = "Hello Go!"
	// 修改data的值 在内存中生成新的StringHeader结构体 并赋值给data
	fmt.Println(data)
	// str内存未改变
	fmt.Println(str)
}

//Hello World!
//Hello Go!
//Hello World!

当声明变量为字符串指针时,变量赋值时对象一定是字符串内存地址,函数传参时拷贝的也是内存地址而已 

package main

import "fmt"


func main()  {
	str := "Hello World!"
	var ptr *string
	// 错误方法 str是字符串类型非指针类型
	//ptr = str
	// 正确方式 获取str的地址 赋值给ptr
	ptr = &str

	fmt.Println(ptr)
	fmt.Println(*ptr)
}

//0xc0000421c0
//Hello World!

  

 数字

数字未找到对应的结构体,数字类型赋值、指针、函数传参与字符串一致,不可修改(修改等同于重新赋值)

package main

import "fmt"

func main()  {

	number := 10
	var ptr *int
	// 错误方法 str是字符串类型非指针类型
	//ptr = str
	// 正确方式 获取str的地址 赋值给ptr
	ptr = &number

	fmt.Println(ptr)
	fmt.Println(*ptr)
}

//0xc00000a0b8
//10

  

 数组

数组赋值、函数传参时,进行都是内存拷贝,数据都会拷贝一份,新的数组修改不影响被赋值的数组

package main

import "fmt"

func main()  {
	list1 := [4] int{1,2,3,4}

	list2 := list1
	list2[0] =100
	fmt.Println(list1)
	fmt.Println(list2)
}

//[1 2 3 4]
//[100 2 3 4]

数组指针,指针修改时不需要加*的;修改时,原数组更改

package main

import "fmt"

func main()  {
	list := [4]int{1,2,3,4}
	// 声明时指定数组大小
	var ptr *[4]int
	ptr = &list
	// 错误赋值
	//*ptr[0] =100
	// 正确方式
	ptr[0] = 100
	fmt.Println(list)
	fmt.Println(*ptr)
}

//[100 2 3 4]
//[100 2 3 4]

 

切片

切片结构体 SliceHeader 如下

type SliceHeader struct {
    // 指向数组内存地址 赋值时拷贝的是数组地址
    Data uintptr
    // 长度
    Len  int
    // 申请空间
    Cap  int
}

赋值、copy、函数传参时只是拷贝了结构体中的变量。详情Go语言【数据结构】切片

package main

import "fmt"

func main()  {
	slice1 := []int{1,2,3,4}

	slice2 := slice1
	slice2[0] =100
	fmt.Println(slice1)
	fmt.Println(slice2)
}

//[100 2 3 4]
//[100 2 3 4]

 切片指针,下面方式都不可以修改

package main

import "fmt"

func main() {
	slice1 := []int{1,2,3,4}
	var ptr *[]int
	ptr = &slice1

	// 下面两种方式都不可以修改
	ptr[0] =100
	*ptr[0] =100
	fmt.Println(slice1)
	fmt.Println(*ptr)
}

//[1 2 3 4]
//[1 2 3 4]

  

channel

通道在赋值时,指向的都是同一块内存地址

package main

import "fmt"

func main() {
	 chan1 := make(chan string,1)
	 chan2 := chan1
	 chan2 <- "hello"
	 data := <-chan1
	 fmt.Println(data)
	 // 指向同一块地址
	 fmt.Println(chan1)
	 fmt.Println(chan2)
}

//hello
//0xc000088000
//0xc000088000

同时,通道也支持指针

package main

import "fmt"

func main() {
	 chan1 := make(chan string,1)
	 chan2 := &chan1
	 *chan2 <- "hello"
	 data := <-chan1
	 fmt.Println(data)
	 fmt.Println(chan1)
	 fmt.Println(chan2)
}

//hello
//0xc000038060
//0xc000006028

  

结构体 

那么重点来了,结构体赋值和指针有何区别,先看戏结构体生成的三种方式,其中第二种方式和第三中方式一致

package main

import "fmt"

type Phone struct {
	color string
	name string
}

func main() {
	// 第一种生成方式  生成结构体对象
	phone1 :=Phone
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇GoCN每日新闻(2019-09-23) 下一篇golang开始篇

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目