go中我遇到的問題總結

go問題總結


1 - go中的nil等于java中的null嗎

在 Go 和 Java 中,nilnull 都用于表示“空值”,但它們的實現和使用方式有所不同。

以下是 Go 中的 nil 和 Java 中的 null 之間的對比:

1. Go 中的 nil

在 Go 中,nil 是一個預定義的常量,表示零值。它的行為根據數據類型的不同而有所不同:

  • 對于指針、切片、映射、通道、接口和函數類型,nil 表示“沒有指向任何地方”。
  • 對于基本數據類型(如 int、float 等),nil 不適用,Go 會使用對應類型的零值(例如 0false"")。
示例:
package mainimport "fmt"func main() {var ptr *intvar arr []intvar ch chan intvar m map[string]intfmt.Println(ptr == nil) // truefmt.Println(arr == nil) // truefmt.Println(ch == nil)  // truefmt.Println(m == nil)   // true
}

2. Java 中的 null

在 Java 中,null 是一個常量,表示沒有對象的引用。它可以賦給任何對象類型的變量,但不能賦給基本數據類型(如 intchar 等)。對于基本數據類型,Java 會使用默認值(例如 0false"")。

示例:
public class Main {public static void main(String[] args) {Integer num = null;String str = null;System.out.println(num == null); // trueSystem.out.println(str == null); // true}
}

3. 對比

特性Go 中的 nilJava 中的 null
適用類型指針、切片、映射、通道、接口、函數等任何對象類型(包括類、接口、數組等)
基本數據類型對于基本數據類型有零值(如 0false對于基本數據類型不適用,使用默認值(如 0
空值判斷可以直接使用 == nil 判斷可以直接使用 == null 判斷

4. 總結

  • nilnull 都表示“沒有值”,但 Go 中的 nil 更為廣泛,適用于多種類型,包括接口、切片等,而 Java 的 null 只能用于對象類型。
  • 在 Go 中,基本數據類型不會使用 nil,而 Java 的基本類型有默認值,不能為 null

2 - go中基本數據類型可以用nil進行判斷嗎

在 Go 中,基本數據類型(如 intfloat64bool 等)不能使用 nil 進行判斷。nil 僅適用于指針、切片、映射、通道、接口、函數等引用類型。對于基本數據類型,Go 會使用相應的零值,而不能將其賦值為 nil


1. 基本數據類型的零值

在 Go 中,基本數據類型有對應的零值,以下是一些常見的零值:

  • int0
  • float640.0
  • boolfalse
  • string""(空字符串)

這些零值與 nil 不同,不能通過 nil 來判斷。

2. 示例:基本數據類型不能用 nil 判斷

package mainimport "fmt"func main() {var i intvar f float64var b boolvar s stringfmt.Println(i == nil)   // 編譯錯誤fmt.Println(f == nil)   // 編譯錯誤fmt.Println(b == nil)   // 編譯錯誤fmt.Println(s == nil)   // 編譯錯誤
}

3. 解決方法

對于基本數據類型,你可以通過比較它們是否等于零值來進行判斷,例如:

package mainimport "fmt"func main() {var i intvar f float64var b boolvar s stringfmt.Println(i == 0)    // truefmt.Println(f == 0.0)  // truefmt.Println(b == false) // truefmt.Println(s == "")   // true
}

4. 總結

  • 基本數據類型不能用 nil 判斷,它們有自己的零值。
  • 對于基本數據類型,應直接與零值進行比較(如 i == 0s == "")。
  • nil 只能用于引用類型(指針、切片、映射等)。

3-結構體方法和普通方法的區別

在 Go 語言中,結構體方法和普通方法(即函數)是兩個常見的概念。雖然它們都定義了代碼的行為,但它們的實現和使用方式有所不同。下面是它們的區別:


1. 結構體方法

結構體方法是與結構體類型(struct)關聯的函數。它們可以訪問和修改結構體的字段。通過給結構體定義方法,可以使結構體類型具備一定的行為。

特點:
  • 結構體方法與某個特定的結構體類型關聯。
  • 結構體方法可以訪問結構體的字段。
  • 結構體方法的接收者是結構體類型或結構體指針。
示例:
package mainimport "fmt"// 定義一個結構體
type Person struct {Name stringAge  int
}// 結構體方法:修改結構體的字段
func (p *Person) SetAge(age int) {p.Age = age
}// 結構體方法:打印結構體內容
func (p Person) Greet() {fmt.Println("Hello, my name is", p.Name, "and I am", p.Age, "years old.")
}func main() {person := Person{Name: "John", Age: 25}person.Greet()    // 輸出: Hello, my name is John and I am 25 years old.person.SetAge(30) // 修改結構體的字段person.Greet()    // 輸出: Hello, my name is John and I am 30 years old.
}

2. 普通方法(函數)

普通方法(即函數)是獨立于任何類型之外的。它不依賴于結構體或其他類型,但它可以作為參數或返回值與其他類型交互。

特點:
  • 普通方法與任何類型無關。
  • 普通方法不能訪問結構體的字段或方法。
  • 普通方法通常用于一般的功能實現,適用于所有類型。
示例:
package mainimport "fmt"// 普通函數:兩個數字相加
func Add(a, b int) int {return a + b
}func main() {result := Add(5, 3) // 調用普通函數fmt.Println("Result of Add:", result) // 輸出: Result of Add: 8
}

3. 主要區別

特性結構體方法普通方法(函數)
與類型的關系與特定類型(如結構體)關聯獨立于任何類型,通常是全局函數
接收者有一個接收者,通常是結構體類型或結構體指針(通過接收者訪問字段)沒有接收者
訪問結構體字段可以訪問結構體字段,通過接收者修改字段值不能訪問結構體的字段
用法用于為結構體添加行為或功能用于實現通用的功能,適用于任何類型

4. 總結

  • 結構體方法:與結構體類型緊密關聯,可以訪問和修改結構體的字段。通過接收者來定義和實現。
  • 普通方法(函數):不與任何類型關聯,不訪問結構體字段,適用于通用功能。

4 - 為什么在struct中實現了String方法,fmt.Println(&stu)就會自動調用你實現的方法

注釋解析:// 如果你實現了 *Student 類型的 String 方法,就會自動調用

這段注釋出現在 Go 語言的代碼中,解釋了當使用 fmt.Println(&stu) 這種方式打印結構體時,Go 是如何處理打印邏輯的。我們來詳細拆解一下:


?? 背景知識:fmt.Println() 是如何工作的?

在 Go 語言中,fmt 包在打印一個值時會嘗試判斷該值是否實現了某些接口,最重要的是:

type Stringer interface {String() string
}

如果某個類型實現了這個接口,fmt 就會自動調用 String() 方法來獲取要打印的字符串。


?? 示例說明:

package mainimport "fmt"type Student struct {Name stringAge  int
}// 給 *Student 類型實現 String 方法
func (s *Student) String() string {return fmt.Sprintf("Student(Name: %s, Age: %d)", s.Name, s.Age)
}func main() {stu := Student{Name: "Tom", Age: 20}fmt.Println(&stu) // 自動調用 (*Student).String() 方法
}

? 注釋解釋:

// 如果你實現了 *Student 類型的 String 方法,就會自動調用
fmt.Println(&stu)
?? 解釋如下:
  • *Student 表示 Student 類型的指針

  • 如果你為 *Student 實現了 String() string 方法:

    func (s *Student) String() string { ... }
    
  • 當你使用 fmt.Println(&stu) 時,fmt 會檢測 *Student 是否實現了 Stringer 接口。

  • 如果實現了,就會自動調用這個方法,而不是打印默認格式的結構體內容。


? 注意事項:

如果你實現的是 Student(非指針)類型的 String() 方法

func (s Student) String() string {// ...
}

那么只有在傳值時(fmt.Println(stu))才會自動調用 String() 方法,fmt.Println(&stu) 不會自動調用。


?? 小結

  • fmt.Println(&stu) 中的 &stu*Student 類型。
  • 如果你為 *Student 實現了 String() 方法,fmt.Println(&stu)自動調用這個方法
  • 這是因為 fmt 包內部會優先調用類型的 String() 方法來打印內容。

5 - (*array)[i][j], (*array)[j][i] = (*array)[j][i], (*array)[i][j]這是什么寫法

? Go 中的多重賦值(多值交換)

(*array)[i][j], (*array)[j][i] = (*array)[j][i], (*array)[i][j]

這是 Go 語言中的 多重賦值(multiple assignment)語法,它允許你在一行中交換兩個值,不需要臨時變量。


?? 等價寫法(更冗長)

temp := (*array)[i][j]
(*array)[i][j] = (*array)[j][i]
(*array)[j][i] = temp

? 使用多重賦值的優勢

  • ? 語法簡潔
  • ? 不需要 temp 臨時變量
  • ? 一行搞定,常用于 交換兩個變量的值

?? 示例

a, b := 3, 5
a, b = b, a
fmt.Println(a, b) // 輸出:5 3

?? 在二維數組轉置中的應用

二維數組轉置時,需要把元素 [i][j][j][i] 的位置互換,原本需要三行代碼,現在一行就能搞定。


?? 小結表格

語法說明
a, b = b, a同時交換兩個變量的值
x, y, z = 1, 2, 3支持多個變量同時賦值
用途交換變量、并行賦值、多返回值接收

6 - go中的函數和方法不是同一個概念嗎

?? Go 中的函數(Function)和方法(Method)不是同一個概念!

雖然它們看起來很像,但本質上有區別。下面是詳細的 Markdown 格式說明:


?? 函數(Function)

Go 中最常見的寫法就是函數。

func Add(a int, b int) int {return a + b
}
? 特點:
  • 沒有“接收者”(receiver)
  • 直接調用,比如:Add(1, 2)
  • 通常是通用工具函數,不依賴某個結構體實例

?? 方法(Method)

方法是綁定到某個**類型(通常是結構體)**的函數。

type Person struct {Name string
}// 方法:帶有接收者
func (p Person) SayHello() {fmt.Println("Hello, my name is", p.Name)
}
? 特點:
  • 有接收者 p Person,表示這個方法是 Person 類型“專屬”的
  • 調用方式:p.SayHello()
  • 方法可以接收值類型(如 Person)或指針類型(如 *Person)作為接收者

?? 方法 vs 函數 的對比表格

項目函數 Function方法 Method
是否有接收者? 無接收者? 有接收者((x Type)
調用方式函數名(參數)對象.方法名()
所屬屬于包(package)屬于某個類型(type)
用途通用計算、工具類邏輯操作特定結構體的數據和行為

? 示例對比

// 普通函數
func SayHi(name string) {fmt.Println("Hi,", name)
}// 方法
type Cat struct {Name string
}func (c Cat) Meow() {fmt.Println(c.Name, "says Meow~")
}

?? 小結

  • ? 函數 是“工具”
  • ? 方法 是“結構體成員行為”
  • 兩者寫法類似,但用途和歸屬不一樣

7 - 方法和函數底層調用機制(值拷貝 vs 指針傳遞) 的區別

?? 方法和函數的底層調用機制(值拷貝 vs 指針傳遞)詳解

/*方法與函數的區別如下:1. 方法(Method)是與某個類型(通常是結構體)綁定的函數。它有一個接收者(receiver),定義格式為:func (接收者名 接收者類型) 方法名(參數...) 返回值 {...}可以通過接收者調用方法,如:instance.MethodName()2. 函數(Function)是獨立的,**沒有接收者**,調用方式為:FunctionName(參數...),不能通過接收者的方式調用。3. 方法的接收者可以是值類型或指針類型:- 值接收者:會復制調用者,不影響原值。- 指針接收者:傳遞地址,可修改原值。4. 方法調用時,Go 支持自動取地址或解引用(語法糖)。如:值對象也可以調用指針接收者方法,反之亦然。5. 函數的參數必須嚴格匹配調用時傳入的參數類型,否則會編譯報錯,不存在自動取地址或解引用。總結:- 方法 = 函數 + 接收者。- 方法更適合面向對象封裝,函數更適合工具類的邏輯。
*/

在 Go 語言中,函數調用和方法調用在底層傳參機制上,其實是一樣的——都是值傳遞,區別在于你傳的是值還是地址


?? 核心概念

方式本質修改是否影響原始變量常用于
值拷貝傳入的是數據的副本? 不影響原始變量小結構體、只讀操作
指針傳遞傳入的是內存地址? 可以影響原始變量修改操作、大結構體

?? 示例:函數中的值傳遞 vs 指針傳遞

type Person struct {Name string
}// 函數:值傳遞
func ChangeNameByValue(p Person) {p.Name = "張三"
}// 函數:指針傳遞
func ChangeNameByPointer(p *Person) {p.Name = "李四"
}
func main() {person := Person{Name: "原名"}ChangeNameByValue(person)fmt.Println("值傳遞結果:", person.Name) // 原名ChangeNameByPointer(&person)fmt.Println("指針傳遞結果:", person.Name) // 李四
}

?? 方法的底層本質

在編譯期間,Go 會把方法轉換成函數調用形式,比如:

func (p Person) Hello() { }

等價于:

func Person_Hello(p Person) { }

如果是指針接收者:

func (p *Person) Hello() { }

等價于:

func Person_Hello(p *Person) { }

?? 進一步理解值 vs 指針調用

type Data struct {Val int
}func (d Data) ByValue() {d.Val = 100fmt.Println("ByValue 中的值:", d.Val)
}func (d *Data) ByPointer() {d.Val = 200fmt.Println("ByPointer 中的值:", d.Val)
}
func main() {d := Data{Val: 10}d.ByValue()fmt.Println("main中值:", d.Val) // 10d.ByPointer()fmt.Println("main中值:", d.Val) // 200
}

?? 編譯器的語法糖

Go 會幫你做這些自動轉換:

  • d.ByPointer() ← 自動加 &,等價于 (&d).ByPointer()
  • (&d).ByValue() ← 自動解引用,等價于 d.ByValue()

只要方法接收者允許,這些轉換會自動進行。


? 小結

對比點值接收者 / 值傳遞指針接收者 / 指針傳遞
是否拷貝結構體? 會? 不會,傳地址
是否修改原對象? 否? 可以
性能開銷?? 拷貝大對象開銷高?? 傳指針更高效
自動轉換支持? 自動加/解引用支持? 自動加/解引用支持

8 - 各種基本類型轉string的常用方法

? Go 中各種基本類型轉換為 string 的常用方法(Markdown 格式)

在 Go 中,將基本數據類型轉換為 string 是開發中的常見需求,以下是常用類型轉換方式的總結:


?? 1. intstring

方法一:使用 strconv.Itoa
import "strconv"i 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77190.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77190.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77190.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【android telecom 框架分析 01】【基本介紹 2】【BluetoothPhoneService為何沒有源碼實現】

1. 背景 我們會在很多資料上看到 BluetoothPhoneService 類,但是我們在實際 aosp 中確找不到具體的實現, 這是為何? 這是一個很好的問題!雖然在車載藍牙電話場景中我們經常提到類似 BluetoothPhoneService 的概念,但…

微機控制電液伺服汽車減震器動態試驗系統

微機控制電液伺服汽車減震器動態試驗系統,用于對汽車筒式減震器、減震器臺架、駕駛室減震裝置、發動機懸置軟墊總成、發動機前置楔形支撐總成等的示功圖試驗、速度特性試驗。 主要的技術參數: 1、最大試驗力:5kN; 2、試驗力測量精…

STM32+dht11+rc522+jq8400的簡單使用

1.dht11的使用 硬件:3v3,gnd,data數據線接一個gpio,三根線即可 軟件: ①dht11.c #include "dht11.h" #include "delay.h" #include "stdbool.h"static STRUCT_DHT11_TYPEDEF dht11;…

AOSP的Doze模式-DeepIdle 初識

前言 從Android 6.0開始,谷歌引入了Doze模式(打盹模式)的省電技術延長電池使用時間。如果用戶長時間未使用設備,低電耗模式會延遲應用后臺 CPU 和網絡活動,從而延長電池續航時間。根據第三方測試顯示,兩臺同樣的Nexus 5&#xff…

用Python Pandas高效操作數據庫:從查詢到寫入的完整指南

一、環境準備與數據庫連接 1.1 安裝依賴庫 pip install pandas sqlalchemy psycopg2 # PostgreSQL # 或 pip install pandas sqlalchemy pymysql # MySQL # 或 pip install pandas sqlalchemy # SQLite 1.2 創建數據庫引擎 通過SQLAlchemy創建統一接口&#xff1a…

每日一題(小白)暴力娛樂篇31

首先分析一下題意,需要求出2024的因子,因為我們要求與2024互質的數字,為什么呢?因為我們要求互質說直白點就是我和你兩個人沒有中間人,我們是自然而然認識的,那我們怎么認識呢,就是直接見面對吧…

電控---printf重定向輸出

在嵌入式系統開發中,printf 重定向輸出是將標準輸出(stdout)從默認設備(如主機終端)重新映射到嵌入式設備的特定硬件接口(如串口、LCD、USB等)的過程。 一、核心原理:標準IO庫的底層…

快速認識:數據庫、數倉(數據倉庫)、數據湖與數據運河

數據技術核心概念對比表 概念核心定義核心功能數據特征典型技術/工具核心應用場景數據庫結構化數據的「電子檔案柜」,按固定 schema 存儲和管理數據,支持高效讀寫和事務處理。實時事務處理(增刪改查),確保數據一致性&…

【17】數據結構之圖的遍歷篇章

目錄標題 圖的遍歷深度優先遍歷 Depth First Search廣度優先遍歷 Breadth First Search 圖的遍歷 從圖中某一個頂點出發,沿著一些邊訪遍圖中所有的頂點,且使用每個頂點僅被訪問一次,這個過程稱為圖的遍歷.Graph Traversal. 其中&#xff0c…

簡單接口工具(ApiCraft-Web)

ApiCraft-Web 項目介紹 ApiCraft-Web 是一個輕量級的 API 測試工具,提供了簡潔直觀的界面,幫助開發者快速測試和調試 HTTP 接口。 功能特點 支持多種 HTTP 請求方法(GET、POST、PUT、DELETE)可配置請求參數(Query …

Git進階操作

Git高階操作完全指南:解鎖專業開發工作流 前言 在當今的軟件開發領域,掌握高級Git技能已成為區分普通開發者與專業開發者的關鍵因素。根據最新的GitHub數據,熟練應用交互式暫存和Rebase等高級功能的開發者,其代碼審查通過率平均提…

Python結合AI生成圖像藝術作品代碼及介紹

為實現生成圖像藝術作品,我選用 Stable Diffusion 庫結合 Python 編寫代碼。下面先展示代碼,再詳細介紹其原理、模塊及使用方法等內容。 生成圖片代碼 import torch from diffusers import StableDiffusionPipeline# 加載預訓練模型 pipe StableDiffu…

Linux操作系統--靜態庫和動態庫的生成and四種解決加載找不到動態庫的四種方法

目錄 必要的知識儲備: 生成靜態庫: 生成動態庫: 解決加載找不到動態庫的四種方法: 第一種:拷貝到系統默認的庫路徑 /usr/lib64/ 第二種:在系統默認的庫路徑/usr/lib64/下建立軟鏈接 第三種&#xff1…

LLM中的N-Gram、TF-IDF和Word embedding

文章目錄 1. N-Gram和TF-IDF:通俗易懂的解析1.1 N-Gram:讓AI學會"猜詞"的技術1.1.1 基本概念1.1.2 工作原理1.1.3 常見類型1.1.4 應用場景1.1.5 優缺點 1.2 TF-IDF:衡量詞語重要性的尺子1.2.1 基本概念1.2.2 計算公式1.2.3 為什么需…

Leetcode 3359. 查找最大元素不超過 K 的有序子矩陣【Plus題】

1.題目基本信息 1.1.題目描述 給定一個大小為 m x n 的二維矩陣 grid。同時給定一個 非負整數 k。 返回滿足下列條件的 grid 的子矩陣數量: 子矩陣中最大的元素 小于等于 k。 子矩陣的每一行都以 非遞增 順序排序。 矩陣的子矩陣 (x1, y1, x2, y2) 是通過選擇…

如何在 Ubuntu 22.04 上安裝、配置、使用 Nginx

如何在 Ubuntu 22.04 上安裝、配置、使用 Nginx?-阿里云開發者社區 更新應用 sudo apt updatesudo apt upgrade檢查必要依賴并安裝 sudo apt install -y curl gnupg2 ca-certificates lsb-release安裝nginx sudo apt install -y nginx# 啟動nginx sudo systemct…

Linux:顯示 -bash-4.2$ 問題(CentOS 7)

文章目錄 一、原因二、錯誤示例三、解決辦法 一、原因 在 CentOS 7 系統中,如果你看到命令行提示符顯示為 -bash-4.2$,一般是 Bash shell 正在運行,并且它沒有找到用戶的個人配置文件,或者這些文件有問題而未能成功加載。這個提示…

QT6 源(34):隨機數生成器類 QRandomGenerator 的源碼閱讀

&#xff08;1&#xff09;代碼來自 qrandom.h &#xff0c;結合官方的注釋&#xff1a; #ifndef QRANDOM_H #define QRANDOM_H#include <QtCore/qalgorithms.h> #include <algorithm> // for std::generate #include <random> // for std::mt1993…

第二篇:linux之Xshell使用及相關linux操作

第二篇&#xff1a;linux之Xshell使用及相關linux操作 文章目錄 第二篇&#xff1a;linux之Xshell使用及相關linux操作一、Xshell使用1、Xshell安裝2、Xshell使用 二、Bash Shell介紹與使用1、什么是Bash Shell(殼)&#xff1f;2、Bash Shell能干什么&#xff1f;3、平時如何使…

MCP(模型上下文協議)學習筆記

學習MCP&#xff08;模型上下文協議&#xff09;的系統化路徑&#xff0c;結合技術原理、工具實踐和社區資源&#xff0c;幫助你高效掌握這一AI交互標準&#xff1a; 在當今人工智能飛速發展的時代&#xff0c;AI技術正以前所未有的速度改變著我們的生活和工作方式。然而&#…