golang经常使用手册:指针、结构体

签名咱们了解了一些golang的基础知识,能够明确的发现golang和c语言非常相似,那么看到这里,你可能更加震惊,这可能就是个新时代的c语言。java

指针golang

变量是一种使用方便的占位符,用于引用计算机内存地址。 Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。数组

示例代码以下:数据结构

package main

import "fmt"

func main() {
   var a int = 10   

   fmt.Printf("变量的地址: %x\n", &a  )
}
复制代码

输出结果以下,可能这里不一样的电脑有一些不一样的输出结果:函数

变量的地址: c420014058
复制代码

指针的概念是:指向任何一个值的内存地址,是内存地址的编号。重点:spa

  • 是go中基本数据类型
  • 表明内存地址
  • 能够指向任意数据的地址
  • 不一样数据类型的指针须要不一样的数据类型和指针符号组合来表示

咱们来看看简单的一些实例:指针

//指针申明格式
// var var_name *var-type
// var-type 为指针类型,var_name 为指针变量名,* 号用于指定变量是做为一个指针。

var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮点型 */

复制代码

指针和其余类型的变量同样,咱们须要申明和赋值后才能使用,看看下面的demo:code

package main

import "fmt"

func main() {

	var a int = 20    /* 声明实际变量 */

	var aPointer *int /* 声明指针变量 */

	aPointer = &a /* 指针变量的存储地址 */

	fmt.Printf("a 变量的地址是: %x\n", &a)

	/* 指针变量的存储地址 */
	fmt.Printf("aPointer 变量储存的指针地址: %x\n", aPointer)

	/* 使用指针访问值 */
	fmt.Printf("*aPointer 变量的值: %d\n", *aPointer)
}
复制代码

输出结果以下(不一样电脑可能实际地址不一样):cdn

a 变量的地址是: c420014050
aPointer 变量储存的指针地址: c420014050
*aPointer 变量的值: 20
复制代码

其实关于指针更加详尽的用法能够看看大学c语言教材,以及数据结构c语言版。对象

空指针

当一个指针被定义后没有分配到任何变量时,它的值为 nil。

nil 指针也称为空指针。

nil在概念上和其它语言的null、None、nil、NULL同样,都指代零值或空值。

一个指针变量一般缩写为 ptr。

注意,指针还有如下操做:

  • 指针数组(核心是数组和指针)
  • 多级指针(指向指针的指针)
  • 函数的指针参数

咱们来看看下面的例子:

package main

import "fmt"

func main() {

	var a int = 20 /* 声明实际变量 */

	var aPointer *int /* 声明指针变量 */

	aPointer = &a /* 指针变量的存储地址 */

	fmt.Printf("a 变量的地址是: %x\n", &a)

	/* 指针变量的存储地址 */
	fmt.Printf("aPointer 变量储存的指针地址: %x\n", aPointer)

	/* 使用指针访问值 */
	fmt.Printf("*aPointer 变量的值: %d\n", *aPointer)

	b := 35
	bPointer := &b

	fmt.Printf("a = %d ,b = %d \n", a, b)
	fmt.Printf("aPointer = %x ,bPointer = %x \n", aPointer, bPointer)

	swap(aPointer, bPointer)

	fmt.Println("交换后的结果")
	fmt.Printf("a = %d ,b = %d \n", a, b)
	fmt.Printf("aPointer = %x ,bPointer = %x \n", aPointer, bPointer)

	pBPtr := &bPointer

	fmt.Printf("pBPtr = %x ,*pBPtr = %x ,**pBPtr = %x \n", pBPtr, *pBPtr, **pBPtr)

}

func swap(a, b *int) {
	tmp := *a

	*a = *b

	*b = tmp
}

复制代码

输出的结果是hi:

a 变量的地址是: c420014050
aPointer 变量储存的指针地址: c420014050
*aPointer 变量的值: 20
a = 20 ,b = 35 
aPointer = c420014050 ,bPointer = c420014060 
交换后的结果
a = 35 ,b = 20 
aPointer = c420014050 ,bPointer = c420014060 
pBPtr = c42000c030 ,*pBPtr = c420014060  ,**pBPtr = 14 
复制代码

在上面的例子中,咱们能够明显的看到a、b的值在交换后发生了变化,可是aPointer和bPointer的值并无发生变化。

在交换函数中,咱们把a、b的值经过指针操做的方式直接更改了,可是aPointer和bPointer是指向了a、b的地址,咱们并无改变他们,则有aPointer和bPointer值没有变化。

接着咱们申明而且初始化了一个二级指针pBPtr,他的值是bPointer这个指针变量的地址,接着*pBPtr的值是bPointer指向的地址也便是b的地址,因此**pBPtr的值是b的值。

结构体

结构体,和咱们在c语言中遇到的同样,用来将不一样数据(不管数据类型是否相同)组装在一块儿。在其余的面向对象语言中,好比说java,咱们习惯来写bean对象,以下:

//在java中建立Person实体
class Person implements Serializable{
    private String name;
    private Integer age;
}
复制代码

那么咱们在go中如何操做呢?

type Person struct {
	name string
	age  int
}
复制代码

固然,咱们不妨看看具体demo:

package main

import "fmt"

type Person struct {
	name string
	age  int
}

//这里是方法,输入Person的方法
func (person Person) logPerson() {
	fmt.Printf("%s,年龄:%d", person.name, person.age)
}

func main() {
	var aPerson Person

	aPerson.name = "go语言"
	aPerson.age = 8
	aPerson.logPerson()

}
复制代码

在上面的代码中,咱们使用了一些知识点:

  • 变量,申明和赋值
  • 包名、导包、主函数
  • 函数、方法
  • 结构体

咱们再主函数中,申明了aPerson变量,且数据类型是结构体Person。而后咱们针对结构体的具体属性进行了初始化,而后调用结构体自身的方法实现了打印Person的相关信息。

固然结构体有一些如下操做:

  • 属性访问,结构体变量名.属性名
  • 相似基本数据类型的使用方法(申明变量、函数参数、指针等)

下面的demo基本阐述告终构体的常规用法:

package main

import "fmt"

type Person struct {
	name string
	age  int
}

func (person Person) logPerson() {
	fmt.Printf("%s,年龄:%d \n", person.name, person.age)
}

func printPersonByPointer(person *Person) {
	fmt.Printf("%s,年龄:%d \n", person.name, person.age)
}

func printPerson(person Person) {
	fmt.Printf("%s,年龄:%d \n", person.name, person.age)
}

func main() {
	var aPerson Person

	aPerson.name = "go语言"
	aPerson.age = 8
	aPerson.logPerson()

	printPersonByPointer(&aPerson)
	
	printPerson(aPerson)
}

复制代码

注意:在go语言中,不支持函数重载

总结

go语言和c语言又不少相似的地方。指针和结构体都是c语言中相似的概念。

  • 指针支持任意数据类型的操做,指针申明格式为:var *name dataType
  • 指针存储内存地址,&是取变量的地址,*是取指针指向内存的值
  • 多级指针的层级
  • 结构体能够称之为扩展数据类型或包装数据类型
  • 结构体用于定义非基本数据类型
  • 结构体的基本操做(属性读写、函数参数、结构体指针)

若是你承认我所作的事情,而且认为我作的事对你有必定的帮助,但愿你也能打赏我一杯咖啡,谢谢。

支付宝捐赠
相关文章
相关标签/搜索