<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Go語言中的函數、方法與接口詳解

馬哥Linux運維 ? 來源:cnblogs ? 2024-04-23 16:21 ? 次閱讀

函數 (function)

函數可以沒有參數或者接受多個參數。

當連續兩個或多個函數的已命名形參類型相同時,除最后一個類型以外,其它都可以省略。

func add(x, y int) int {

return x + y

}

函數(或者變量)的名稱以大寫字母開頭時,它就是已導出的。

函數可以返回任意數量的字符串。

func swap(x, y string) (string, string) {

return y, x

}

函數的返回值可以被命名,它們會被視作在函數頂部定義的變量,沒有參數的 return 返回已經被命名的返回值。

func division(dividend, divisor int) (quotient, remainder int) {

quotient = dividend / divisior

remainder = dividend - quotient * divisor

return

}

函數也是值,也可以用作函數的參數和返回值。

// conpute 接受一個函數作為參數

// 調用 conpute 時傳入不同的函數,返回對3和4作不同的操作的結果

func conpute(fn func(float64, float64) float64) float64 {

return fn(3, 4)

}

函數的閉包 (closure)

A closure is a record storing a function together with an environment.

閉包是由函數和環境組合而成的。閉包保存和記錄了它產生時的外部環境——它的函數體之外的變量,并且可以訪問和修改這些變量。

在閉包實際實現的時候,往往通過調用一個外部函數返回其內部函數來實現的。用戶得到一個閉包,也等同于得到了這個內部函數,每次執行這個閉包就等同于執行內部函數。

如果外部函數的變量可見性是 local 的,即生命周期在外部函數結束時也結束的,那么閉包的環境就是封閉的。反之,那么閉包其實不再封閉,全局可見的變量的修改,也會對閉包內的這個變量造成影響。

package main

import “fmt”

func test_1(x int) func() {

return func() {

x++

fmt.Println(x)

}

}

func test_2(x int) func() {

sum := 0

return func() {

sum += x

fmt.Println(x, sum)

}

}

func test_3(x int) func(int) int {

sum := 0

return func(y int) int {

sum += x * y

return sum

}

}

func main() {

test_1(1)()

test_2(1)()

// 每個閉包事實上有著不同的外部環境

// 即:對每個 for 循環,都會新建一個 test_3()

// 所以每個閉包綁定的是不同的 sum 變量

for i := 0; i 《 5; i++ {

fmt.Printf(“%d ”, test_3(1)(i))

}

fmt.Println()

// 每個閉包的外部環境相同(tmp)

// 即 for 循環中的閉包綁定的是同一個 sum 變量

tmp := test_3(1)

for i := 0; i 《 5; i++ {

fmt.Printf(“%d ”, tmp(i))

}

fmt.Println()

}

上面的程序輸出結果是:

2

1 1

1 1

0 1 2 3 4

0 1 3 6 10

方法 (method)

Go 沒有類,不過可以為結構體類型定義方法。方法就是一類帶特殊的接收者參數的函數。方法接收者在它自己的參數列表內,位于 func 關鍵字和方法名之間。(非結構體類型也可以定義方法)

type Vertex struct {

X, Y float64

}

func (v Vertex) distance() float64 {

return math.Sqrt(v.X*v.X + v.Y*v.Y)

}

方法并不能修改指針接收者的值。只有指針接收者的方法能夠修改接收者指向的值。(在這種情況下,方法也沒有修改接收者的值——指針的內容,只是修改了指針指向的值,和用指針作為參數是一樣的)

在很多意義上,方法的接收者和普通的參數是一樣的。如果不使用指針。

不過,帶指針參數的函數必須接受一個指針,而以指針為接受者的方法被調用時,接受者接收者既能為值又能為指針。

package main

import “fmt”

type Vertex struct {

X, Y float64

}

func (v *Vertex) Move_1(dx, dy float64) {

v.X += dx

v.Y += dy

}

func (v Vertex) Move_2(dx, dy float64) {

v.X += dx

v.Y += dy

}

func Move_3(v *Vertex, dx, dy float64) {

v.X += dx

v.Y += dy

}

func Move_4(v Vertex, dx, dy float64) {

v.X += dx

v.Y += dy

}

func main() {

var v Vertex

v.X = 0

v.Y = 0.

v.Move_1(1, 1)

fmt.Println(v.X, v.Y)

p := &v

p.Move_1(1, 1)

fmt.Println(v.X, v.Y)

v.Move_2(1, 1)

fmt.Println(v.X, v.Y)

Move_3(&v, 1, 1)

fmt.Println(v.X, v.Y)

Move_4(v, 1, 1)

fmt.Println(v.X, v.Y)

}

上面的程序輸出結果是:

1 1

2 2

2 2

3 3

3 3

接口 (interface)

接口是一組方法簽名的集合,接口類型的變量可以保存任何實現了這些方法的值。

Go 語言中的接口是隱式實現的,也就是說,如果一個類型實現了一個接口定義的所有方法,那么它就自動地實現了該接口。沒有 implements 關鍵字。

type MyFloat float64

func (f MyFloat) Abs() float64 {

if f 《 0 {

return float64(-f)

}

return float64(f)

}

type Vertex struct {

X, Y float64

}

func (v *Vertex) Abs() float64 {

return math.Sqrt(v.X*v.X + v.Y*v.Y)

}

type Abser interface {

Abs() float64

}

func main() {

var a Abser

f := MyFloat(-math.Sqrt2)

v := Vertex{3, 4}

a = f // MyFloat 實現了 Abs()

a = &v // *Vertex 實現了 Abs()

}

指定了零個方法的接口值被稱為空接口,可以保存任何類型的值(因為每個類型都至少實現了零個方法)??战涌诒挥脕硖幚砦粗愋偷闹?。

在內部,接口值可以看做包含值和具體類型的元組,類型斷言提供了訪問接口值底層具體值的方式。

package main

import “fmt”

func main() {

var i interface{} = “hello”

// 該語句斷言接口值 i 保存了具體類型 string,

// 并將其底層類型為 string 的值賦予變量 s。

// 若 i 并未保存 string 類型的值,該語句就會觸發 panic。

s := i.(string)

fmt.Println(s)

// 為了判斷一個接口值是否保存了一個特定的類型,

// 類型斷言可返回兩個值:其底層值以及一個報告斷言是否成功的布爾值。

// 若 i 保存了一個 string,那么 s 將會是其底層值,而 ok 為 true。

// 否則,ok 將為 false 而 s 將為 T 類型的零值,程序并不會產生 panic。

s, ok := i.(string)

fmt.Println(s, ok)

f, ok := i.(float64)

fmt.Println(f, ok)

f = i.(float64) // 報錯 (panic)

fmt.Println(f)

}

上面的程序輸出結果是:

hello

hello true

0 false

panic: interface conversion: interface {} is string, not float64

。..。..

審核編輯:黃飛

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 字符串
    +關注

    關注

    1

    文章

    553

    瀏覽量

    20232
  • 函數
    +關注

    關注

    3

    文章

    4117

    瀏覽量

    61467
  • 變量
    +關注

    關注

    0

    文章

    598

    瀏覽量

    28153
  • go語言
    +關注

    關注

    1

    文章

    156

    瀏覽量

    8948

原文標題:Go 的函數,方法和接口

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Go語言中的整數類型

    Go 語言中,整型可以細分成兩個種類十個類型。
    發表于 07-20 15:25 ?372次閱讀

    C語言中指針函數函數指針的概念及應用示例

    在C語言中,指針函數函數指針是強大且常用的工具。它們允許我們以更靈活的方式處理函數和數據,進而擴展程序的功能。
    發表于 08-16 16:14 ?367次閱讀

    C語言中函數的基本知識

    函數是C語言中的基本構建塊之一,它允許我們將代碼組織成可重用、模塊化的單元。
    發表于 08-16 18:25 ?409次閱讀

    如何使用單擊右鍵選中函數go to definition來查看定義在匯編文件下的函數?

    如圖所示,函數OSStartHighRdy();是定義在匯編文件下的一個函數,怎樣可以像C語言中函數一樣,單擊右鍵選中 go to def
    發表于 08-22 01:01

    C語言中atoi()函數應該怎么用?

    C語言中atoi()函數應該怎么用?
    發表于 10-14 09:10

    剖析什么是C語言中的隱式函數聲明

    「1、什么是C語言的隱式函數聲明」 在C語言中,函數在調用前不一定非要聲明。如果沒有聲明,那么編譯器會自動按照一種隱式聲明的規則,為調用函數
    的頭像 發表于 05-25 09:38 ?3420次閱讀
    剖析什么是C<b class='flag-5'>語言中</b>的隱式<b class='flag-5'>函數</b>聲明

    詳細介紹go語言中的閉包的實現

    什么是閉包? 什么場景下會用閉包 ? 本文對 go 語言中的閉包做了詳細介紹。 閉包是由函數及其相關引用環境組合而成的實體(即:閉包=函數+引用環境)。
    的頭像 發表于 10-20 16:18 ?1707次閱讀

    帶你了解go語言中的閉包

    ? 【 導讀】什么是閉包? 什么場景下會用閉包 ? 本文對 go 語言中的閉包做了詳細介紹。 閉包是由函數及其相關引用環境組合而成的實體(即:閉包=函數+引用環境)。
    的頭像 發表于 11-02 15:27 ?2232次閱讀

    詳解回調函數的概念及使用步驟

    回調函數就是一個被作為參數傳遞的函數。在C語言中,回調函數只能使用函數指針實現,在C++、Python、ECMAScript等更現代的編程
    的頭像 發表于 05-26 15:20 ?3698次閱讀

    C語言怎么跳出while函數

    在C語言中while函數是經常用到的,這里說一下可以跳出while函數的幾種方法。
    的頭像 發表于 06-17 15:40 ?3.3w次閱讀
    C<b class='flag-5'>語言</b>怎么跳出while<b class='flag-5'>函數</b>

    C語言中函數的創建以及使用

    下面我們來介紹一下 C 語言中一個非常重要的概念 - 函數 (function)。首先就要先給函數下一個定義,函數就是完成特定任務的獨立代碼單元,這也就是說,一個
    的頭像 發表于 07-06 09:38 ?4969次閱讀

    go語言中怎么使用HTTP代理

    go語言中怎么使用HTTP代理。
    的頭像 發表于 09-01 14:41 ?2228次閱讀

    嵌入式Linux應用開發之go方法與類成員函數

    Go語言中,接口就是方法簽名(Method Signature)的集合。當一個類型實現了接口中的所有
    發表于 05-13 09:53 ?273次閱讀

    c語言中函數函數體用什么符號括起來

    都知道函數是數學里的重要組成部分,數學中我們常見到函數的概念,但是你了解C語言中函數嗎?其實函數就相當于一個子程序,那什么是子程序呢? 在
    的頭像 發表于 11-24 15:52 ?385次閱讀
    c<b class='flag-5'>語言中</b><b class='flag-5'>函數</b>的<b class='flag-5'>函數</b>體用什么符號括起來

    如何給C語言中函數定義兩個不同的名字?

    最近有位哥問我,如何給C語言中函數定義兩個不同的名字?就是這兩個名字都是指向同一個函數,同一個地址,而且兩個名字都可以當做函數來用的那種。
    的頭像 發表于 12-19 16:21 ?371次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>