golang函數說明,golang指針運算

本文目錄一覽:

GO語言學習系列八——GO函數(func)的聲明與使用

GO是編譯性語言,所以函數的順序是無關緊要的,為了方便閱讀,建議入口函數 main 寫在最前面,其餘函數按照功能需要進行排列

GO的函數 不支持嵌套,重載和默認參數

GO的函數 支持 無需聲明變數,可變長度,多返回值,匿名,閉包等

GO的函數用 func 來聲明,且左大括弧 { 不能另起一行

一個簡單的示例:

輸出為:

參數:可以傳0個或多個值來供自己用

返回:通過用 return 來進行返回

輸出為:

上面就是一個典型的多參數傳遞與多返回值

對例子的說明:

按值傳遞:是對某個變數進行複製,不能更改原變數的值

引用傳遞:相當於按指針傳遞,可以同時改變原來的值,並且消耗的內存會更少,只有4或8個位元組的消耗

在上例中,返回值 (d int, e int, f int) { 是進行了命名,如果不想命名可以寫成 (int,int,int){ ,返回的結果都是一樣的,但要注意:

當返回了多個值,我們某些變數不想要,或實際用不到,我們可以使用 _ 來補位,例如上例的返回我們可以寫成 d,_,f := test(a,b,c) ,我們不想要中間的返回值,可以以這種形式來捨棄掉

在參數後面以 變數 … type 這種形式的,我們就要以判斷出這是一個可變長度的參數

輸出為:

在上例中, strs …string 中, strs 的實際值是b,c,d,e,這就是一個最簡單的傳遞可變長度的參數的例子,更多一些演變的形式,都非常類似

在GO中 defer 關鍵字非常重要,相當於面相對像中的析構函數,也就是在某個函數執行完成後,GO會自動這個;

如果在多層循環中函數里,都定義了 defer ,那麼它的執行順序是先進後出;

當某個函數出現嚴重錯誤時, defer 也會被調用

輸出為

這是一個最簡單的測試了,當然還有更複雜的調用,比如調試程序時,判斷是哪個函數出了問題,完全可以根據 defer 列印出來的內容來進行判斷,非常快速,這種留給你們去實現

一個函數在函數體內自己調用自己我們稱之為遞歸函數,在做遞歸調用時,經常會將內存給佔滿,這是非常要注意的,常用的比如,快速排序就是用的遞歸調用

本篇重點介紹了GO函數(func)的聲明與使用,下一篇將介紹GO的結構 struct

Golang入門到項目實戰 | golang 函數

函數的go語言中的一級公民,我們把所有的功能單元都定義在函數中,可以重複使用。函數包含函數的名稱、參數列表和返回值類型,這些構成了函數的簽名(signature)。

函數在使用之前必須先定義,可以調用函數來完成某個任務。函數可以重複調用,從而達到代碼重用。

go語言函數定義語法

語法解析:

go語言函數定義實例

定義一個求和函數

定義一個比較兩個數大小的函數

go語言函數調用

當我們要完成某個任務時,可以調用函數來完成。調用函數要傳遞參數,如何有返回值可以獲得返回值。

運行結果

Golang 中函數和方法的區別

在接觸到go之前,我認為函數和方法只是同一個東西的兩個名字而已(在我熟悉的c/c++,python,java中沒有明顯的區別),但是在golang中者完全是兩個不同的東西。官方的解釋是,方法是包含了接收者的函數。到底什麼意思呢。

首先函數的格式是固定的,func+函數名+ 參數 + 返回值(可選) + 函數體。例

func main()

{

fmt.Println(“Hello go”)

}

在golang中有兩個特殊的函數,main函數和init函數,main函數不用介紹在所有語言中都一樣,它作為一個程序的入口,只能有一個。init函數在每個package是可選的,可有可無,甚至可以有多個(但是強烈建議一個package中一個init函數),init函數在你導入該package時程序會自動調用init函數,所以init函數不用我們手動調用,l另外它只會被調用一次,因為當一個package被多次引用時,它只會被導入一次。

package main

import (

“demo/mypackage”

“fmt”

)

func main() {

fmt.Println(“Hello go…. I = “, mypackage.I)

}

運行結果:

我們可以看到,程序為我們自動調用了兩個init函數,並且是按照順序調用的。

下面來看方法。

package main

import “fmt”

type myint int

//乘2

func (p *myint) mydouble() int {

*p = *p * 2

return 0

}

//平方

func (p myint) mysquare() int {

p = p * p

fmt.Println(“mysquare p = “, p)

return 0

}

func main() {

var i myint = 2

i.mydouble()

fmt.Println(“i = “, i)

i.mysquare()

fmt.Println(“i = “, i)

}

運行結果:

我們可以看到方法和函數的區別,方法在func關鍵字後是接收者而不是函數名,接收者可以是自己定義的一個類型,這個類型可以是struct,interface,甚至我們可以重定義基本數據類型。我們可以給他一些我們想要的方法來滿足我們的實際工程中的需求,就像上面一樣我重定義了int並給了它一個乘2和平法的方法,這裡我們要注意一個細節,接收者是指針和非指針的區別,我們可以看到當接收者為指針式,我們可以通過方法改變該接收者的屬性,但是非指針類型缺做不到。

這裡的接收者和c++中的this指針有一些相似,我們可以把接受者當作一個class,而這些方法就是類的成員函數,當接收者為指針類型是就是c++中的非const成員函數,為非指針時就是const成員函數,不能通過此方法改變累的成員變數。

golang 怎麼定義可變參數的函數

golang定義可變參數的函數方法是:

—- 採用ANSI標準形式時,參數個數可變的函數的原型聲明是:

type funcname(type para1, type para2, …)

—- 這種形式至少需要一個普通的形式參數,後面的省略號不表示省略,而是函數原型的一部分。type是函數返回值和形式參數的類型。

—- 採用與UNIX System V兼容的聲明方式時,參數個數可變的函數原型是:

type funcname(va_alist)

va_dcl

—- 這種形式不需要提供任何普通的形式參數。

type是函數返回值的類型。va_dcl是對函數原型聲明中參數va_alist的詳細聲明,實際是一個宏定義,對不同的硬體平台採用不同的類型來定義,但在最後都包括了一個分號。因此va_dcl後不再需要加上分號了。va_dcl在代碼中必須原樣給出。va_alist在VC中可以原樣給出,也可以略去。

此外,採用頭文件stdarg.h編寫的程序是符合ANSI標準的,可以在各種操作系統和硬體上運行;而採用頭文件varargs.h的方式僅僅是為了與以前的程序兼容。所以建議使用前者。

golang-redis系列——返回值助手函數(二)

從上一節的內容可知,Do() 和 Receive() 等方法的返回值,除了 error 外,是一個 interface{} 類型的返回值,因此當我們的複雜操作返回的不是基本數據類型時,就需要我們自己解析返回值,例如,當我們利用 HMGET 方法獲取一批返回值時,就需要對返回結果進行解析,具體如下:

由於返回值是多條數據,因此需要先將 reply 轉成 []interface 類型,然後在遍歷結果時在分別轉成 []uint8 (byte數組), 最後再轉成 string 類型。

隨著我們操作複雜度,數據解析的工作量也會非常大,(lua 腳本的使用,會使結果的解析更為複雜,因為可能存在多種類型的結果一起返回的情況,lua 腳本相關的內容會在下一節介紹)。

redigo 包中的返回值助手函數的存在,就是為了幫助我們完成這些枯燥繁瑣的數據解析過程。

返回值助手函數相關源碼路徑為 github.com/gomodule/redigo/redis/reply.go 提供的主要方法如下:

上述返回值助手函數的具體使用,應該依據具體的命令進行選擇。如果大家還記得上一節介紹的 Redis 基本數據類型,可能會有些疑問,對於 redis 來說,其數據據存儲本質都是 []bytes, 為什麼可以解析出 Int、int64、float等類型的數據呢?

我們以 Float64() 為例進行說明,具體源碼如下:

其實,返回值助手函數是將 []byte 類型的原始數據,利用 strconv.ParseFloat(string(reply), 64) 轉換成了 float64類型,因此在我們使用過程中返回值助手函數的選擇,應該基於業務和實際存儲的數據格式為依據。我們以第一小節的示例為例,看返回值助手函數如何降低我們的工作量,具體如下:

除了使用返回值助手函數對上述固定結構的結果進行解析外,redigo 包還提供了一個 Scan()函數用於解析自定義的複雜數據結構,我們依然以上一個示例進行說明,具體示例如下:

如果返回結果為結構化切片,也可以使用 canSlice() 方法,從而簡化 loop 處理的部分,具體示例如下:

通過上述的示例,我們介紹了 scan 函數的基本用法,但是細心的同學可能會發現嗎,為什麼數據寫入時,value 的類型為 []int64 但是讀取時只能按照 string 類型讀取呢。這是因為 Redis 底層存儲的數據本質都是 string 類型,。 無論是 HMSET 還是 MSET 最終都只能按照 string 類型讀取,因為其本質都是 hash 結構,不同之處僅在於 HMSET 是嵌套的 hash類型。 因此,[]int64 數據在寫入階段,就已經被自動處理為 []byte,寫入 redis 之後,len 和 類型 屬性會丟失。

如果強行按照 []int64解析將出錯:

如果 value 必須以結構化的數據存儲,那麼可以提前對要寫入的數據進行編碼,例如 json、protobuf 等,取出後再進行解碼獲得原始數據。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/187869.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-28 06:25
下一篇 2024-11-28 06:26

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字元串操作中,capitalize函數常常被用到,這個函數可以使字元串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • 三角函數用英語怎麼說

    三角函數,即三角比函數,是指在一個銳角三角形中某一角的對邊、鄰邊之比。在數學中,三角函數包括正弦、餘弦、正切等,它們在數學、物理、工程和計算機等領域都得到了廣泛的應用。 一、正弦函…

    編程 2025-04-29
  • 單片機列印函數

    單片機列印是指通過串口或並口將一些數據列印到終端設備上。在單片機應用中,列印非常重要。正確的列印數據可以讓我們知道單片機運行的狀態,方便我們進行調試;錯誤的列印數據可以幫助我們快速…

    編程 2025-04-29
  • Python3定義函數參數類型

    Python是一門動態類型語言,不需要在定義變數時顯示的指定變數類型,但是Python3中提供了函數參數類型的聲明功能,在函數定義時明確定義參數類型。在函數的形參後面加上冒號(:)…

    編程 2025-04-29
  • Python定義函數判斷奇偶數

    本文將從多個方面詳細闡述Python定義函數判斷奇偶數的方法,並提供完整的代碼示例。 一、初步了解Python函數 在介紹Python如何定義函數判斷奇偶數之前,我們先來了解一下P…

    編程 2025-04-29
  • Python實現計算階乘的函數

    本文將介紹如何使用Python定義函數fact(n),計算n的階乘。 一、什麼是階乘 階乘指從1乘到指定數之間所有整數的乘積。如:5! = 5 * 4 * 3 * 2 * 1 = …

    編程 2025-04-29
  • 指針Python:為什麼Python中不需要使用指針?

    在Python中,指針的使用不像其他語言一樣那麼常見。這是因為Python有自己的內存管理方式,所以在大多數情況下,不需要顯式地使用指針。那麼,為什麼Python中不需要使用指針呢…

    編程 2025-04-29
  • 使用Golang調用Python

    在現代軟體開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇…

    編程 2025-04-29

發表回復

登錄後才能評論