Golang學習系列第三天:學習數組、切片、Map、結構體、指針、函數、介面類型、channel通道

来源:https://www.cnblogs.com/dongguangming/archive/2020/07/15/13311198.html
-Advertisement-
Play Games

繼Golang學習系列第二天:變數、常量、數據類型和流程語句之後,今天開始學習數據類型之高級類型: 派生類型。 學過java的人都知道,java其實就8種基本類型:byte、short、int、long、float、double、char、boolean,但它有引用數據類型:字元串、數組、集合、類、 ...


 

       繼Golang學習系列第二天:變數、常量、數據類型和流程語句之後,今天開始學習數據類型之高級類型: 派生類型。

學過java的人都知道,java其實就8種基本類型:byte、short、int、long、float、double、char、boolean,但它有引用數據類型:字元串、數組、集合、類、介面等。

而golang也有這樣的劃分,基本類型(Golang學習系列第二天已學過)和派生類型(不叫引用類型),派生類型有以下幾種:數組類型、切片類型、Map類型、結構體類型(struct)、指針類型(Pointer)、函數類型、介面類型(interface)、Channel 類型。

 

1.  數組類型

數組是具有相同數據類型的元素序列。 數組在聲明中定義了固定的長度,因此不能擴展超過該長度。 數組聲明為

var variable_name [SIZE] variable_type

讓我們以代碼舉例如下

package main

import "fmt"

func main() {
    var city [5]string
    city[0] = "北京"
    city[1] = "上海"
    city[2] = "廣州"
    city[3] = "深圳"
    city[4] = "濮陽"
    fmt.Println(city[0], city[1], city[2], city[3], city[4])
    fmt.Println(city)
}

將變數city聲明為5個字元串的數組,執行輸出

不過也可以在聲明數組時設置數組條目,看簡潔版

package main

import "fmt"

func main() {
    var city = [5]string{ "北京", "上海","廣州","深圳","濮陽"}
    fmt.Println(city[0], city[1], city[2], city[3], city[4])
    fmt.Println(city)
    
    //簡寫版
    othercity := [5]string{ "北京", "上海","廣州", "深圳","濮陽"}
    fmt.Printf("%q", othercity)
}

輸出結果

甚至,當您傳遞值時,可以使用省略號來使用隱式長度

package main

import "fmt"

func main() {
    var city = [5]string{ "北京", "上海","廣州","深圳","濮陽"}
    fmt.Println(city[0], city[1], city[2], city[3], city[4])
    fmt.Println(city)
    
    //簡寫版
    othercity := [5]string{ "北京", "上海","廣州", "深圳","濮陽"}
    fmt.Printf("%q\n", othercity)
    
     //隱士長度
    other_city := [...]string{ "北京", "上海","廣州", "深圳","濮陽"}
    fmt.Printf("%q", other_city)
}

輸出結果

 以不同方式列印數組

註意我們使用帶Printf的fmt包以及如何使用%q“動詞”來列印每個引用的元素。

如果我們使用Println或%s動詞,我們將得到不同的結果

package main

import "fmt"

func main() {  
     //不同方式列印數組
    other_city := [...]string{ "北京", "上海","廣州", "深圳","濮陽"}
    fmt.Println("不同方式列印數組")
    fmt.Println(other_city)
    fmt.Printf("%s\n", other_city)
    fmt.Printf("%q", other_city)
}

執行後輸出如圖

 

多維數組

您還可以創建多維數組,示例代碼:

package main

import "fmt"

func main() {
    var multi [2][3]int
    for i := 0; i < 2; i++ {
        for j := 0; j < 3; j++ {
            multi[i][j] = i + j
        }
    }
    fmt.Println("二維數組: ", multi)
}

輸出結果

 

2.  切片Slices類型

切片包裝數組可為數據序列提供更通用,更強大和更方便的介面。 除了具有明確維數的項(例如轉換矩陣)外,Go中的大多數數組編程都是使用切片而不是簡單數組完成的。

切片包含對基礎數組的引用,如果您將一個切片分配給另一個,則兩個切片都引用同一數組。 如果函數採用slice參數,則對slice的元素所做的更改將對調用者可見,這類似於將指針傳遞給基礎數組。

切片指向值數組,並且還包含長度。 切片可以調整大小,因為它們只是另一個數據結構之上的包裝。

例如, []T is a slice with elements of type T 表示[] T是具有T類型元素的切片。

舉個小例子

package main

import "fmt"

func main() {
    var city = []string{ "北京", "上海","廣州","深圳","濮陽"}
    fmt.Println(city[0], city[1], city[2], city[3], city[4])
    fmt.Println(city)
}

2.1  切分切片

可以對切片進行切片,以創建一個指向相同數組的新切片值。表達式為

slice[start:end]

表示計算從start到end-1(含)的元素的一部分。

註意:start和end是表示索引的整數。

下麵舉個小demo

package main

import "fmt"

func main() {
    var city = []string{ "北京", "上海","廣州","深圳","濮陽","鄭洲"}
    
    fmt.Println(city)
	fmt.Println(city[1:4])

	// missing low index implies 0
	fmt.Println(city[:3])
	// [2 3 5]

	// missing high index implies len(s)
	fmt.Println(city[4:])
}

輸出結果

2.2   製造切片

除了通過立即傳遞值(切片文字)來創建切片之外,還可以使用make關鍵字創建切片。 您創建一個特定長度的空切片,然後填充每個條目。

package main

import "fmt"

func main() {

	fmt.Println("準備用make方式創建切片")
	cities := make([]string, 3)
	cities[0] = "鄭洲"
	cities[1] = "濮陽"
	cities[2] = "安陽"
	fmt.Printf("%q", cities)
}

輸出結果:

 它通過分配清零的數組並返回引用該數組的切片來工作。

 

2.3  附加到切片

可以通過append方式附加值到切片中

package main

import "fmt"

func main() {
	//附加到切片
	other_cities := []string{}
	other_cities = append(other_cities, "濮陽")
	fmt.Println(other_cities)
}

看輸出結果

 

也可以同時附加多個值到切片中,示例代碼同時包括兩個城市鄭洲和濮陽

package main

import "fmt"

func main() {
  
	//附加多值到切片
	other_cities := []string{}
	
	other_cities = append(other_cities, "鄭洲","濮陽")
	
	fmt.Println(other_cities)
}

輸出結果

 

甚至您還可以使用省略號將切片附加到另一個切片

package main

import "fmt"

func main() {
	fmt.Println("準備用make方式創建切片")
	cities := make([]string, 3)
	cities[0] = "鄭洲"
	cities[1] = "濮陽"
	cities[2] = "安陽"
	fmt.Printf("%q\n", cities)
	
	//附加切片到切片
	other_cities := []string{"南京"}
	
	other_cities = append(other_cities,  cities...)
	
	fmt.Println(other_cities)
}

輸出結果

註意: 省略號是該語言的內置功能,這意味著該元素是一個集合。 我們無法將字元串類型([] string)類型的元素附加到字元串切片中,只能附加字元串。 但是,在切片後使用省略號(...),表示要附加切片的每個元素。 因為我們要從另一個片段追加字元串,所以編譯器將接受操作,因為類型是匹配的。

您顯然無法將[] int類型的切片附加到[] string類型的另一個切片中。

 

2.4  複製切片

切片也可以複製。 在這裡,我們創建一個與other_cities長度相同的空切片copycities,並從other_cities複製到copycities中。

package main

import "fmt"

func main() {
   
	fmt.Println("準備用make方式創建切片")
	cities := make([]string, 3)
	cities[0] = "鄭洲"
	cities[1] = "濮陽"
	cities[2] = "安陽"
	fmt.Printf("%q\n", cities)
	
	//附加多值到切片
	other_cities := []string{"南京"}
	
	other_cities = append(other_cities,  cities...)
	
	fmt.Println(other_cities)
	
	//拷貝切片
    fmt.Println("準備用copy方式創建切片")
    copycities := make([]string, len(other_cities))
    copy(copycities, other_cities)
    fmt.Println("copycities:", copycities)
}

輸出結果 

2.5  切片長度

您可以隨時使用len檢查切片的長度。

package main

import "fmt"

func main() {
    fmt.Println("準備用make方式創建切片")
	cities := make([]string, 3)
	cities[0] = "鄭洲"
	cities[1] = "濮陽"
	cities[2] = "安陽"
	fmt.Printf("%q\n", cities)
	
	//附加多值到切片
	other_cities := []string{"南京"}
	
	other_cities = append(other_cities,  cities...)
	
	fmt.Println(other_cities)
	
	//列印切片長度
	fmt.Println(len(cities))
	countries := make([]string, 42)
	fmt.Println(len(countries))
}

輸出結果

2.6  零片

切片的零值為nil。 無切片的長度和容量為0。

package main

import "fmt"

func main() {
	//零片
	var temp []int
    fmt.Println(temp, len(temp), cap(temp))
    if temp == nil {
        fmt.Println("nil!")
    }
}

 輸出結果

 

3. map類型

Map 是一種無序的鍵值對的集合,Map 最重要的一點是通過 key 來快速檢索數據,key 類似於索引,指向數據的值。

Map 是一種集合,所以我們可以像迭代數組和切片那樣迭代它。不過,Map 是無序的,我們無法決定它的返回順序,這是因為 Map 是使用 hash 表來實現的。

package main

import "fmt"

func main() {
	users := map[string]int{
		"admin":       0,
		"donguangming":       1,
		"student":           2,
	}

	fmt.Printf("%#v", users)
}

輸出結果

 

當不使用上述map時,使用前必須使用make(不是新的)創建map。 nil映射為空,無法分配給它。

package main

import "fmt"

type User struct {
	name string
	age int
	city string
}

var user map[string]User

func main() {

    //通過make創建
	user = make(map[string]User)

	user["dgm"] = User{"董廣明", 99, "南京"}
	fmt.Println(user["dgm"])
}

輸出結果

 

3.1  操作map

 3.1.1  在map中插入或更新元素

m[key] = elem

  3.1.2    查詢一個元素

elem = m[key]

  3.1.3  刪除一個元素

delete(m, key)

   3.1.4  測試鍵是否存在並且有值

elem, ok = m[key]

如果鍵在m中,則確定為true。 如果不是,則ok為false,elem為map元素類型的零值。 同樣,從map中讀取時(如果沒有按鍵)則結果是map元素類型的零值。

綜上合起來代碼如下

	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在“JavaScript圖形實例:曲線方程”一文中,我們給出了15個曲線方程繪製圖形的實例。這些曲線都是根據其曲線方程,在[0,2π]區間取一系列角度值,根據給定角度值計算對應的各點坐標,然後在計算出的坐標位置描點,從而繪製出曲線。 我們可以將曲線的繪製過程動態展示出來。 例如,對於星形線的繪製,編 ...
  • 許可權管理系統中,菜單也屬於許可權控制的一個資源,應該直接應用於角色,和許可權功能點一樣,屬於角色控制的一環。不同角色用戶,登錄系統後,出現的系統菜單是不同的。在VUE+Element 前端中,我們菜單結合路由集合,實現可訪問路由的過濾,也就實現了對應角色菜單的展示和可訪問路由的控制,詳細可以參考隨筆《循... ...
  • 2020 年真的是災禍頻發,但是在各類前端框架上,依舊是在穩步的推進。近日 Vue 團隊更新了關於 Vue 3 的最新狀態,尤大新增了三個語法糖特性,它們將用於優化 SFC 的開發體驗,你會有興趣嘗鮮試試麽~ 登高遠眺 天高地迥,覺宇宙之無窮 前端框架 Vue 3: 2020 年中的狀態更新 近日 ...
  • 橋接模式的概念與實現 為什麼叫橋接模式 橋接模式的適用場景 繼承是面向對象的三大特性之一,但很多時候使用繼承的結果卻不盡如人意。除了人盡皆知的緊耦合問題外,有的時候還會導致子類的快速膨脹。 設想這樣一個場景:最初設計的時候有一個類型Product,但後來隨著新需求的出現,X原因導致了它的變化,X有兩 ...
  • 本專欄內容均引用《大話設計模式》並做適當修改, 起因 有部分電腦專業的學生或有一定經驗的在職開發者,他們都知道類、方法、構造方法、甚至抽象類、介面等概念,並用各種IDE寫過不少的Windows或Web程式,但是當問到為什麼要用面向對象,它的好處在哪裡,卻沒有人能完整的講出來,多數人的反應是,概念知 ...
  • 關於延遲載入 在 Spring 中,預設情況下所有定的 bean 及其依賴項目都是在應用啟動時創建容器上下文是被初始化的。測試代碼如下: @Slf4j @Configuration public class DemoConfig { public DemoConfig() { log.warn(" ...
  • 一、複習一下前面所學的內容 1.寫出下列字元或者數字的類型以及在printf()函數中使用什麼符號轉換 常量類型轉換說明(%轉換符號) 12 int %d 0X3 unsigned int %#x 'C' char(實際上是int) %c 2.34E07 double %e '\040' char( ...
  • 安裝python的mysqlclient==1.4.6報錯 環境:ubuntu18.04python 3.6.8Django 2.0 想要使用Django來操作MySQL,需要安裝一個驅動程式。在Python3中,選擇用mysqlclient做驅動。 安裝mysqlclient出現報錯: ERROR ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...