1. 程式人生 > >go語言基礎學習

go語言基礎學習

一、函式function

1、基本概念

函式是基本的程式碼塊,用於執行一個任務。
Go 語言最少有個 main() 函式
函式宣告告訴了編譯器函式的名稱,返回型別,和引數
Go 語言標準庫提供了多種可動用的內建的函式。例如,len() 函式可以接受不同型別引數並返回該型別的長度。如果我們傳入的是字串則返回字串的長度,如果傳入的是陣列,則返回陣列中包含的函式個數。

2、函式定義

函式定義格式如下:

func function_name( [parameter list] ) [return_types] {
   函式體
}

函式定義解析:

  • func:函式由 func 開始宣告
  • function_name
    :函式名稱,函式名和引數列表一起構成了函式簽名。
  • parameter list:引數列表,引數就像一個佔位符,當函式被呼叫時,你可以將值傳遞給引數,這個值被稱為實際引數。引數列表指定的是引數型別、順序、及引數個數。引數是可選的,也就是說函式也可以不包含引數。
  • return_types:返回型別,函式返回一列值。return_types 是該列值的資料型別。有些功能不需要返回值,這種情況下 return_types 不是必須的。
  • 函式體:函式定義的程式碼集合。

示例:

/* 函式返回兩個數的最大值 */
func max(num1, num2 int) int {
   /* 宣告區域性變數 */
   var
result int if (num1 > num2) { result = num1 } else { result = num2 } return result }

3、函式特性

  • Go 函式不支援巢狀、過載和預設引數
  • Go 函式支援無需宣告原型、不定長度變參、多返回值、命名返回值引數、匿名函式、閉包
  • 定義函式使用關鍵字func,且左大括號不能另起一行
  • 函式也可以作為一種型別使用
ackage main


import "fmt"  

func main() {
  A(1, 2, 3, 4 ,5)
}


// ... 不定長變參
func
A(a ...int)
{ fmt.Println(a) }

輸出:

➜  myfirstgo go run func.go
[1 2 3 4 5]

不定長變參特性:
1、不可以在不定長變參後邊新增其他引數 func b(a ...int, b string), 這種寫法是錯誤
2、不定長引數可以放在其他引數後邊 func b(b string, a ...int)

4、匿名函式

func main() {

  // 將一個函式賦值一個變數,該變數是函式型別
  a := func(){
    fmt.Println("匿名函式")
}

  // 呼叫
  a()
}

5、閉包

/**
* 閉包函式
*
* 該閉包函式接收一個int型引數,其返回值是函式型別
*
*/
func closure(x int) func(int) int {
    fmt.Println("%p\n", &x)
    return func (y int) int {

        fmt.Println("%p\n", &x)
        fmt.Println(x)
        fmt.Println(y)
    
        return x + y
    }
}

func main() {
  f := closure(10);
  fmt.Println(f(1))
  fmt.Println(f(2))
}

列印結果:

➜  myfirstgo go run func.go
%p
 0xc42000e228
%p
 0xc42000e228
10
1
11
%p
 0xc42000e228
10
2
12
➜  myfirstgo

6、defer

  • defer 的執行方式類似其他語言中的解構函式,在函式體執行結束後按照呼叫順序的相反順序逐個執行
  • 即使函式發生嚴重錯誤也會執行
  • 支援匿名函式的呼叫
  • 常用於資源清理、檔案關閉、解鎖以及記錄時間等操作
  • 通過與匿名函式配合可在return之後修改函式計算結果
  • 如果函式體內某個變數作為defer時匿名函式的引數,則在定義defer時即已經獲得了拷貝,否則則是引用某個變數的地址
  • Go沒有異常機制,但有 panic/recover 模式來處理錯誤
  • Panic 可以在任何地方引發,但 recover 只有在 defer 呼叫的函式中有效

簡單的測試:


func main() {
  fmt.Println("a")
  
  defer fmt.Println("b")
  defer fmt.Println("c")
}

上邊的執行會列印什麼結果呢? 會列印:a b c 嗎?
讓我們實際執行一下:

  myfirstgo go run func.go
a
c
b

實際列印的結果為:a c b

defer 的執行方式類似其他語言中的解構函式,在函式體執行結束後按照呼叫順序的相反順序逐個執行

使用閉包

func main() {
  for i := 0; i < 3; i++ {

       // defer 普通呼叫
       // defer fmt.Println(i)  // 列印 2 1 0

     // 使用閉包,引用區域性變數
       defer func () {
           fmt.Println(i)
       }()

  }
  
}

列印結果:

➜  myfirstgo go run func.go
3
3
3

panic 使用示例

func main() {
  A()
  B()
  C()
}

func A() {
    fmt.Println("FUNC A")
}

func B() {

   // 匿名函式,如果沒有引數,則末尾需要使用括號
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("Recover is B")

        }
        
    }()

    panic("B panic")

}

func C() {
    fmt.Println("FUNC C")
}

列印結果:

➜  myfirstgo go run func.go
FUNC A
Recover is B
FUNC C
➜  myfirstgo

二、結構Struct

1.基本概念

Go 語言中陣列可以儲存同一型別的資料,但在結構體中我們可以為不同項定義不同的資料型別
結構體由一系列具有相同型別或不同型別的資料構成的資料集合
結構體表示一項記錄,比如儲存圖書館的書籍記錄,每本書有以下屬性:
Title :標題
Author : 作者
Subject:學科
ID:書籍ID

2.結構體定義

結構體定義需要使用 type 和 struct 語句。struct 語句定義一個新的資料型別,結構體中有一個或多個成員。type 語句設定了結構體的名稱。結構體的格式如下:

type struct_variable_type struct {
   member definition;
   member definition;
   ...
   member definition;
}

一旦定義了結構體型別,它就能用於變數的宣告,語法格式如下:

variable_name := structure_variable_type {value1value2...valuen}

type 是定義名稱,struct 是結構體型別,如同 int 型別一樣。

結構體可以包含多種資料型別,陣列只能是單一型別的資料集合。

訪問結構體成員
如果要訪問結構體成員,需要使用點號 (.) 操作符,格式為:"結構體.成員名"
結構體型別變數使用struct關鍵字定義,例項如下:

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}

func main() {
   var Book1 Books        /* 宣告 Book1 為 Books 型別 */
   var Book2 Books        /* 宣告 Book2 為 Books 型別 */

   /* book 1 描述 */
   Book1.title = "Go 語言"
   Book1.author = "www.runoob.com"
   Book1.subject = "Go 語言教程"
   Book1.book_id = 6495407

   /* book 2 描述 */
   Book2.title = "Python 教程"
   Book2.author = "www.runoob.com"
   Book2.subject = "Python 語言教程"
   Book2.book_id = 6495700

   /* 列印 Book1 資訊 */
   fmt.Printf( "Book 1 title : %s\n", Book1.title)
   fmt.Printf( "Book 1 author : %s\n", Book1.author)
   fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
   fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)

   /* 列印 Book2 資訊 */
   fmt.Printf( "Book 2 title : %s\n", Book2.title)
   fmt.Printf( "Book 2 author : %s\n", Book2.author)
   fmt.Printf( "Book 2 subject : %s\n", Book2.subject)
   fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id)
}

以上例項執行執行結果為:

Book 1 title : Go 語言
Book 1 author : www.runoob.com
Book 1 subject : Go 語言教程
Book 1 book_id : 6495407
Book 2 title : Python 教程
Book 2 author : www.runoob.com
Book 2 subject : Python 語言教程
Book 2 book_id : 6495700

3.struct特性

  • Go中的struct與C中的struct非常相似,並且Go沒有class
  • 使用 type <Name> struct{} 定義結構,名稱遵循可見性規則
  • 支援指向自身的指標型別成員
  • 支援匿名結構,可用作成員或定義成員變數
  • 匿名結構也可以用於map的值
  • 可以使用字面值對結構進行初始化
  • 允許直接通過指標來讀寫結構成員
  • 相同類似的成員可進行直接拷貝賦值
  • 支援 == 與 != 比較運算子,但不支援 > 或 <
  • 支援匿名欄位,本質上是定義了以某個型別名為名稱的欄位
  • 嵌入結構作為匿名欄位看起來像繼承,但不是繼承
  • 可以使用匿名欄位指標

示例:

package main


import "fmt"  

type person struct{
    Name string
    Age int
}

func main() {


  a := person{
      Name:"Jam",
      Age:19,
  }
  // a.Age = 20


  fmt.Println(a)


}

列印:

➜  myfirstgo go run struct.go
{Jam 19}

傳遞指標變數:

package main


import "fmt"  

type person struct{
    Name string
    Age int
}

func main() {


  a := person{
      Name:"Jam",
      Age:19,
  }
  // a.Age = 20
  fmt.Println(a)


  A(a)

  // 值拷貝,如果需要原來的改變,則需要新增指標
  B(&a)

  fmt.Println(a)


}

// per 為變數名,person表示為結構體型別
func A(per person) {
    per.Age = 25
    fmt.Println("A", per)
}

// per 為變數名,person表示為結構體型別
func B(per *person) {
    per.Age = 18
    fmt.Println("B", per)
}

列印:

➜  myfirstgo go run struct.go
{Jam 19}
A {Jam 25}
B &{Jam 18}
{Jam 18}

或者在初始化結構體時,獲取到變數地址並賦值變數,這樣做的好處是在傳遞引數時,不需要傳遞地址符號了,只需在函式定義時,給引數加星號即可。

package main


import "fmt"  

type person struct{
    Name string
    Age int
}

func main() {

 // 在結構初識化時,我們習慣取地址符號,這樣a就為指向某個結構的指標
  a := &person{
      Name:"Jam",
      Age:19,
  }

  a.Name = "Corwien"

  // a.Age = 20
  fmt.Println(a)


  A(a)

  // 值拷貝,如果需要原來的改變,則需要新增指標
  B(a)

  fmt.Println(a)


}

// per 為變數名,person表示為結構體型別
func A(per *person) {
    per.Age = 25
    fmt.Println("A", per)
}

// per 為變數名,person表示為結構體型別
func B(per *person) {
    per.Age = 18
    fmt.Println("B", per)
}

列印:

➜  myfirstgo go run struct.go
&{Corwien 19}
A &{Corwien 25}
B &{Corwien 18}
&{Corwien 18}

匿名結構:
匿名結構,沒有名稱的結構體

func main() {


// 匿名結構,沒有名稱的結構體
  a := struct {
      Name string
      Age int
  }{
      Name:"Corwien",
      Age: 20,
  }

  fmt.Println(a)

}

列印:

➜  myfirstgo go run struct.go
{Corwien 20}

匿名結構巢狀:

type person struct{
    Name string
    Age int
    Contact struct {
        Phone, City string
        Code int           // 門牌號
    }
}

func main() {
    a := person{Name:"Corwien", Age:15}
    a.Contact.Phone = "10086"
    a.Contact.City = "Guangzhou"
    a.Contact.Code = 2007
  
    fmt.Println(a)

}

列印:

➜  myfirstgo go run struct.go
{Corwien 15 {10086 Guangzhou 2007}}

匿名欄位:

匿名欄位:結構體沒有命名結構體屬性的欄位,只有型別,匿名欄位必須嚴格遵守欄位型別宣告的順序。

type person struct{
    string
    int
}

func main() {

    // 匿名欄位必須嚴格遵守欄位型別宣告的順序
    a := person{"Corwien", 12}
    
    fmt.Println(a)

}

列印:

➜  myfirstgo go run struct.go
{Corwien 12}

結構型別比較

type person struct{
    Name string
    Age int
}

func main() {

    // 匿名欄位必須嚴格遵守欄位型別宣告的順序
    a := person{Name:"Corwien", Age:12}
    b := person{Name:"Corwien", Age:12}
    
    fmt.Println(a == b)

}

列印:

➜  myfirstgo go run struct.go
true

Go如何繼承呢

我們知道其他語言有繼承,比如相同的屬性,我們不必重複去寫,只需繼承父類的公共屬性即可。遺憾的是Go沒有繼承,但Go有組合.

package main

import "fmt"  

// 嵌入結構作為匿名欄位
type human struct {
    Sex int
}

type teacher struct {
    human            // Go會將嵌入欄位預設作為屬性名,所以在賦值時需要這樣寫:human: human{Sex: 1}
    Name string
    Age int
}

type student struct {
    human
    Name string
    Age int
}

func main() {

    a := teacher{Name:"Corwien", Age:25, human: human{Sex: 1}}
    b := student{Name:"mark", Age:12, human: human{Sex: 1}}
    
    a.Name = "Jack"
    a.Age = 10
    // a.human.Sex = 0
    a.Sex = 0
    fmt.Println(a, b)

}

列印:

➜  myfirstgo go run struct.go
{{0} Jack 10} {{1} mark 12}

三、方法method

1.基本概念

Go不像其它面相物件語言一樣可以寫個class,然後在class裡面寫一堆方法,但是它也很巧妙的實現了這種效果,我們只需要在普通函式前面加個接受者(receiver,寫在函式名前面的括號裡面),這樣編譯器就知道這個函式(方法)屬於哪個struct了

method是附屬在一個給定的型別上,語法和函式的宣告語法幾乎一樣,只是再func後面增加了一個recevier(也就是method所依從的主體)

2.method定義

func (r ReceiverType) funcName(parameters) (results)

形象一點說,就是 ReceiverType 型別的所有欄位,方法 funcName 都是可以使用的,可以認為 funcName 屬於 ReceiverType

示例:

package main

import (
    "fmt"
    "math"
)

type Rectangle struct {
    width, height float64
}
type Circle struct {
    radius float64
}

func (r Rectangle) area() float64 {
    return r.width * r.height
}
func (c Circle) area() float64 {
    return c.radius * c.radius * math.Pi
}
func main() {
    r1 := Rectangle{12, 
            
           

相關推薦

go語言基礎學習

一、函式function 1、基本概念 函式是基本的程式碼塊,用於執行一個任務。Go 語言最少有個 main() 函式。函式宣告告訴了編譯器函式的名稱,返回型別,和引數。 Go 語言標準庫提供了多種可動用的內建的函式。例如,len() 函式可以接受不同型別引數並返回該

GO語言學習(五)Go 語言基礎語法

序列 單行 break ani 開頭 ntp false nil div Go 標記 Go 程序可以由多個標記組成,可以是關鍵字,標識符,常量,字符串,符號。如以下 GO 語句由 6 個標記組成: fmt.Println("Hello, World!")

go語言基礎資料結構學習---- 陣列, 列表(list)和切片(slice)

go語言基礎資料結構學習–> 陣列, 列表(list)和切片(slice) go 語言中的 陣列是型別相同的元素的集合, 列表是雙鏈表的容器, 可以新增不同型別的資料 切片是對現有陣列的引用, 比陣列更方便靈活, 還可以追加資

go語言基礎資料結構學習 ---- 字典(map)

go語言基礎資料結構學習–> 字典(map) go 語言中的字典和python 中的字典特性差不多 相同: 鍵值對, 無序集合, 每個鍵都是唯一的, 對一個鍵多次賦值會更新當前鍵的值; 不同: go語言的字典裡面的型別是定好的, 不可變更, python可以隨

Go語言基礎入門學習線路圖+開源專案推薦

Go作為近兩年迅速流行起來的程式語言始終致力於使事情簡單化。它並未引入很多新概念,而是聚焦於打造一門簡單的語言,讓開發者使用起來感覺異常快速且簡單。相信有意向深入學習Go語言的小夥伴都在研究Go的開源專案,今天我就把自己覺得不錯的6個Go開源專案和學習線路圖分享給大家,希望大家能獲得收穫和成長。 Go語

Go學習筆記-go語言基礎

Go 語言共有 25 個關鍵字,全部為小寫: breakdefault funcinterfaceselect casedefer gomap struct chanelse gotopackage

Go語言基礎單元測試示例

== stat 示例 語言 單元 ould true def 函數 這個要熟悉原理,要能寫。。 但現在。。。。。 註意,沒有main函數,以_test.go結尾,命令go test -v package main import ( "testing"

java語言基礎go語言基礎的區別

clas pan 搭建 pat classpath spa jdk java strong 一:開發環境搭建 1、java語言的開發環境搭建 我的電腦, 屬性,高級設置,環境變量 (1)在系統變量點新建 變量名:JAVA_HOME,變量值:把JDK的根目錄復制放在這 (2

Java語言基礎學習筆記(七)

day tez lec mdk abd err .com mar mdm 烈7A茨諳9m繁5暗MChttp://www.zcool.com.cn/collection/ZMTg3NzE1Njg=.html 3馗iC蓖17握WM啦http://www.zcool.com.cn

go 語言 基礎 類型(1)

必須 const 表達式 基本 基本類 image 關鍵字 字符串 函數 變量 使用關鍵字 var定義變量,自動初始化為0值。如果提供初始化值,可省略變量類型,由編譯器自動推斷。 在函數內部可以使用 := 方式定義變量 func main() { x := 123

2、c語言基礎學習02

操作系統 一個 常用快捷鍵 risc u+ 可執行 上傳 二進制位 寫法 =============================================================================將windows的可執行文件上傳到linux,

c語言基礎學習06

cas clu 小知識 fputs 轉義字符 而已 參與 子串 翻譯 =============================================================================涉及到的知識點有:1、C語言庫函數、字符輸入函數:

go語言值得學習的開源項目推薦

實現 新手學 谷歌 post pca 語言 memcached target 開源項目 谷歌官方維護了一個基於go語言的開源項目列表: https://github.com/golang/go/wiki/Projects 其中有非常多的優秀項目值得學習,有幾百行代碼適合

Go語言【第十四篇】:Go語言基礎總結

cal pro 結果 第十四 深入 得到 divider math XP Go語言類型轉換 類型轉換用於將一種數據類型的變量轉換為另外一種類型的變量,Go語言類型轉換基本格式如下: type_name(expression) type_name為類型,expression為

Go語言基礎介紹

unit plain inter mage popu 函數返回 int cto 可選 Go是一個開源的編程語言。Go語言被設計成一門應用於搭載Web服務器,存儲集群或類似用途的巨型中央服務器的系統編程語言。目前,Go最新發布版本為1.10. Go語言可以運

Go語言開發(二)、Go語言基礎

Go 語言 基礎 Go語言開發(二)、Go語言基礎 一、Go語言程序結構 Go語言程序基本結構如下:A、包聲明B、引入包C、函數D、變量E、語句 & 表達式F、註釋 package main //包聲明 import "fmt" //引入包 func main(){ //main函數

go語言 http學習

get ram stax serve config lan asi html text net/http庫學習 概念 處理器 處理器:擁有ServeHTTP方法的接口(任何類型) 簽名:ServeHTTP(http.ResponseWriter, *http.Requ

Go語言開發學習教程

教程 學習 cto 性能 開發 語言 內置 程序 com Go語言開發學習教程 Go語言開發學習教程目錄如下: Go語言開發(一)、Go語言簡介http://blog.51cto.com/9291927/2126775Go語言開發(二)、Go語言基礎http://blog.

Java語言基礎——學習筆記

練習題 pub 使用 取數據 以及 九九 思想 問題 進行 04.01_Java語言基礎(循環結構概述和for語句的格式及其使用) A:循環結構的分類 for,while,do...while B:循環結構for語句的格式: for(初始化表達式;條件表達式;循環

SQL語言基礎學習

進行 ima com span 知識 一次 語言 sql 技術分享 9.26。對之前學習的知識進行一下梳理,同時結合所查資料對知識進行一次整合 SQL語言基礎學習