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
  • 指針存儲內存地址,&是取變量的地址,*是取指針指向內存的值
  • 多級指針的層級
  • 結構體能夠稱之爲擴展數據類型或包裝數據類型
  • 結構體用於定義非基本數據類型
  • 結構體的基本操做(屬性讀寫、函數參數、結構體指針)

若是你承認我所作的事情,而且認爲我作的事對你有必定的幫助,但願你也能打賞我一杯咖啡,謝謝。

支付寶捐贈
相關文章
相關標籤/搜索