golang結構體與指針類型

結構體與指針類型

指針類型字段

具名字段

舉例

package struct_knowledgeimport "fmt"//結構體字段為指針類型
func StructWithPoint(){type Student struct{name *string}var lisa Studentfmt.Printf("賦值前,Student的實例的值%#v\n",lisa)//錯誤的賦值方法//報錯:panic: runtime error: invalid memory address or nil pointer dereference// *lisa.name = "hello"//正確的賦值方法1name := "lisa"lisa.name = &namefmt.Printf("賦值后,Student的實例的值%#v\n",lisa)//正確賦值方法2//先分配內存再賦值lisa.name = new(string)*lisa.name = "hello"fmt.Printf("賦值后,Student的實例的值%#v\n",lisa)
}

結果

賦值前,Student的實例的值struct_knowledge.Student{name:(*string)(nil)}
賦值后,Student的實例的值struct_knowledge.Student{name:(*string)(0xc000186050)}
賦值后,Student的實例的值struct_knowledge.Student{name:(*string)(0xc000186060)}

注意事項

一定要注意指針的內存分配,沒有分配內存的指針不能賦值。

//方法1:這種是在棧上分配內存
name := "lisa"
lisa.name = &name
fmt.Printf("賦值后,Student的實例的值%#v\n",lisa)//方法2:在堆上賦值
//先分配內存再賦值
lisa.name = new(string)
*lisa.name = "hello"
fmt.Printf("賦值后,Student的實例的值%#v\n",lisa)

匿名字段

匿名指針類型字段,實際上字段名就是去除*號的類型名,舉例

//報錯:string redeclared
type Student struct{*stringstring
}//實際上等價于
type Student struct{//出現了同名字段所以報錯string *stringstring string
}

舉例

package struct_knowledgeimport "fmt"//結構體字段為指針類型
func StructWithPoint(){type Student struct{*string}var lisa Studentfmt.Printf("賦值前,Student的實例的值%#v\n",lisa)//錯誤的賦值方法//報錯:panic: runtime error: invalid memory address or nil pointer dereference// *lisa.string = "hello"//正確的賦值方法1name := "lisa"lisa.string = &namefmt.Printf("賦值后,Student的實例的值%#v\n",lisa)//正確賦值方法2//先分配內存再賦值lisa.string = new(string)*lisa.string = "hello"fmt.Printf("賦值后,Student的實例的值%#v\n",lisa)
}

結果

賦值前,Student的實例的值struct_knowledge.Student{name:(*string)(nil)}
賦值后,Student的實例的值struct_knowledge.Student{name:(*string)(0xc0000140a0)}
賦值后,Student的實例的值struct_knowledge.Student{name:(*string)(0xc0000140b0)}

指針類型嵌套結構體

具名結構體

和普通字段的處理情況一樣,舉例

舉例

package struct_knowledge
import "fmt"
//結構體指針
func StructWithPoint1(){type Animal struct{name string }type Dog struct{Anl *Animal}var dog Dog/*報錯:panic: runtime error: invalid memory address or nil pointer dereference[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x490830]*/// dog.Anl.name = "duby"// fmt.Printf("賦值后,dog的實例的值%#v\n",dog)//方法1:先分配內存dog.Anl = &Animal{}dog.Anl.name = "duby"fmt.Printf("賦值后,dog的實例的值%#v\n",dog)//方法2:使用new方法dog.Anl = new(Animal)dog.Anl.name = "duby"fmt.Printf("賦值后,dog的實例的值%#v\n",dog)
}

結果

賦值后,dog的實例的值struct_knowledge.Dog{Anl:(*struct_knowledge.Animal)(0xc0000140a0)}
賦值后,dog的實例的值struct_knowledge.Dog{Anl:(*struct_knowledge.Animal)(0xc0000140b0)}

匿名結構體

和匿名字段一樣

type Animal struct{name string 
}
type Dog struct{*Animal
}//等價于
type Dog struct{Animal *Animal
}

注意

當使用指針類型的匿名結構體后,普通匿名結構體的特性就失去了,

舉例

//匿名結構體
func StructWithPoint2(){type Animal struct{name string }type Dog struct{*Animal}var dog Dog/*報錯:panic: runtime error: invalid memory address or nil pointer dereference[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x490830]*/// dog.name = "Mao"// fmt.Printf("賦值后,dog的實例的值%#v\n",dog)//指針都需要先分配nick := &Animal{name:"Mao"}dog = Dog{nick,}fmt.Printf("賦值后,dog的實例的值%#v\n",dog)//也可以采用具名結構體一樣的處理方式,例如dog.Animal = new(Animal)dog.Animal.name = "duby"fmt.Printf("賦值后,dog的實例的值%#v\n",dog)}

對于普通匿名結構體,我們可以用頂層結構體名.字段名來訪問嵌套結構體。

但是指針類型的嵌套結構體會報指針未分配內存的問題,所以我們我們必須給指針類型的結構體分配內存。

結果

賦值后,dog的實例的值struct_knowledge.Dog{Animal:(*struct_knowledge.Animal)(0xc0000140a0)}
賦值后,dog的實例的值struct_knowledge.Dog{Animal:(*struct_knowledge.Animal)(0xc0000140b0)}

接收者類型

結構體的方法的接收者可以為指針也可以為值。

由于結構體是值類型的,所以當方法接收者使用的是值時,方法內的操作與外部無關;

當方法接收者是指針時,方法內的操作會影響到外部的原始變量。

舉例

package struct_knowledgeimport "fmt"type Day struct{Name string Order int 
}func (d Day) ChangeVal(){if d.Order==1 {d.Name = "星期一"}else{d.Name = "未知"}fmt.Printf("接收者為值類型時,方法內的實例值為%#v\n",d)
}func (d *Day) ChangeValByPorint(){if d.Order==1 {d.Name = "星期一"}else{d.Name = "未知"}fmt.Printf("接收者為值類型時,方法內的實例值為%#v\n",d)
}

調用

package mainimport ("fmt""go_learn/struct_knowledge"
)
func main(){var day struct_knowledge.Dayday.Order = 1day.ChangeVal()fmt.Printf("接收者為值類型時,方法外的實例值為%#v\n",day)day.ChangeValByPorint()fmt.Printf("接收者為指針類型時,方法外的實例值為%#v\n",day)
}

結果

接收者為值類型時,方法內的實例值為struct_knowledge.Day{Name:"星期一", Order:1}
接收者為值類型時,方法外的實例值為struct_knowledge.Day{Name:"", Order:1}
接收者為值類型時,方法內的實例值為&struct_knowledge.Day{Name:"星期一", Order:1}
接收者為指針類型時,方法外的實例值為struct_knowledge.Day{Name:"星期一", Order:1}

理解

1.方法的接收者是指針還是值不是由其調用者決定的,而是由方法本身決定的,如果方法的接收者為指針,方法就會自動取調用者的指針。

var day struct_knowledge.Day
day.Order = 1//調用者都是 Day實例
// changeVal這個方法使用的是實例的值
day.ChangeVal()
//ChangeValByPorint這個方法使用的是實例的指針
day.ChangeValByPorint()

2.結構體指針問題:結構體實例指針的使用形式和其值的使用形式是一樣的,所以一定要明確使用的是值還是指針。

golang為了美觀,將數組和結構體實例指針前的*去除了。

func (d Day) ChangeVal(){if d.Order==1 {d.Name = "星期一"}else{d.Name = "未知"}fmt.Printf("接收者為值類型時,方法內的實例值為%#v\n",d)
}func (d *Day) ChangeValByPorint(){if d.Order==1 {d.Name = "星期一"}else{d.Name = "未知"}fmt.Printf("接收者為值類型時,方法內的實例值為%#v\n",d)
}

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

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

相關文章

NetMizer-日志管理系統-遠程命令執行漏洞挖掘

漏洞描述:NetMizer 日志管理系統 cmd.php中存在遠程命令執行漏洞,攻擊者通過傳入 cmd參數即可命令執行 1.fofa搜素語句 title"NetMizer 日志管理系統" 2.漏洞驗證 網站頁面 驗證POC /data/manage/cmd.php?cmdid

Contactile三軸觸覺傳感器:多維力感賦能機器人抓取

在非結構化環境中,機器人對物體的精準抓取與操作始終面臨巨大挑戰。傳統傳感器因無法全面感知觸覺參數(如三維力、位移、摩擦),難以適應復雜多變的場景。Contactile推出的三軸觸覺力傳感器,通過仿生設計與創新光學技術…

OpenCV三維解算常用方法C++

如果標定過程是通過OpenCV張正友標定法實現的,得到的內參外參保存在.txt文件中是這樣的形式: ① 內參intrinsics.txt: ② 外參extrinsics.txt: 那么可以通過如下方法讀取.txt文件獲取左右相機內外參,主要包括三維解算…

棧和隊列相關知識題目

棧的底層原理 棧(Stack)是一種后進先出(LIFO)?的線性數據結構,所有操作(如插入、刪除)僅在棧頂進行。它的底層實現可以是數組或鏈表,具體取決于編程語言和應用場景。 1.基于數組實…

【實戰案例】永洪vividime:精準賦能零售行業,實現數據洞察與業務增長

在零售食品行業變革加速、市場競爭白熱化的背景下,XX集團作為休閑食品領域頭部企業,面臨消費趨勢變化、宏觀經濟承壓及業績增長乏力的多重挑戰。為破解增長困境,集團將“收入增長金額”確立為核心戰略指標(北極星指標)…

一些題目記錄

別人面經題目記錄 https://zhuanlan.zhihu.com/p/32626732052 實現 NMS,七八次,很高頻; 實現 MultiHeadSelfAttention,大概 三四次; 用 Numpy 或者 List 實現MLP 的前向和反向,4次; Leetcode …

面試題分享-多線程順序打印奇偶數

目錄 1.題目詳情 2.解題思路 2.1.分析題目 2.2.解析思路 3.代碼實現 4.運行結果 1.題目詳情 昨天刷抖音,遇到一個面試題,描述如下: 請使用兩個線程,分別順序交替打印奇數和偶數,直到10為止。例如有兩個線程&#…

模型 杜根定律

系列文章分享模型,了解更多👉 模型_思維模型目錄。信心>能力、行動導向、未來時態。 1 杜根定律的應用 1.1 公共政策博弈——底特律市長杜根的保險改革攻堅戰 核心挑戰:底特律市長Mike Duggan面臨汽車保險費率畸高導致居民陷入貧困循環的…

關于在vscode中的Linux 0.11 應用程序項目的生成和運行

首先我們需要需要查看鏡像文件 查看軟盤鏡像文件 floppyb.img 中的內容 在 VSCode 的“Terminal”菜單中選擇“Run Build Task...”,會在 VSCode 的頂部中間位置彈出一個 可以執行的 Task 列表,選擇其中的“打開 floppyb.img”后會使用 Floppy Editor …

使用CSS3實現炫酷的3D視差滾動效果

使用CSS3實現炫酷的3D視差滾動效果 這里寫目錄標題 使用CSS3實現炫酷的3D視差滾動效果項目概述核心技術實現1. 3D空間的創建2. 視差層級設置3. 動畫效果實現流星動畫月亮發光效果 技術難點與解決方案1. 層級重疊問題2. 性能優化3. 響應式適配 開發心得總結 項目概述 在這個項目…

作業12 (2023-05-15 指針概念)

第1題/共11題【單選題】 關于指針的概念,錯誤的是:( ) A.指針變量是用來存放地址的變量 B.指針變量中存的有效地址可以唯一指向內存中的一塊區域 C.野指針也可以正常使用 D.局部指針變量不初始化就是野指針 回答正確 答案解析: A:正確,指針變量中存儲的是一個地址,指…

【ESP32S3】esp32獲取串口數據并通過http上傳到前端

通過前面的學習(前面沒發過,因為其實就是跑它的demo)了解到串口配置以及開啟線程實現功能的工作流程,與此同時還有esp32作為STA節點,將數據通過http發送到服務器。 將這兩者聯合 其實是可以得到一個:esp32獲…

《鴻蒙攜手AI:解鎖智慧出行底層邏輯》

在科技飛速發展的當下,智慧出行成為人們對未來交通的美好期許,而鴻蒙系統與人工智能的深度融合,正為這一愿景的實現提供強大助力。從技術原理角度深入剖析,鴻蒙系統究竟如何支撐人工智能在智慧出行場景中的應用呢?這背…

MyBatis-Plus緩存機制深度解析與SpringBoot整合實戰

一、MyBatis-Plus緩存機制全景解析 MyBatis-Plus在MyBatis原生緩存基礎上進行了深度增強,形成了多層次的緩存體系: 1. 緩存層級架構 應用層 ├── MP擴展緩存(多租戶/邏輯刪除) ├── 二級緩存(Mapper級別,跨Session共享) └── 一級緩存(SqlSession級別,默認開…

Day38 | 1365. 有多少小于當前數字的數字、941. 有效的山脈數組、1207. 獨一無二的出現次數、283. 移動零、189. 輪轉數組

1365. 有多少小于當前數字的數字 題目鏈接&#xff1a;1365. 有多少小、于當前數字的數字 - 力扣&#xff08;LeetCode&#xff09; 題目難度&#xff1a;簡單 代碼&#xff1a; class Solution {public int[] smallerNumbersThanCurrent(int[] nums) {Map<Integer,Inte…

數據人的進階之路:四年數倉實踐與成長思考

前言 在數據倉庫開發的過程中&#xff0c;常常會遇到很多值得思考的問題&#xff0c;它們不僅關乎技術的深度&#xff0c;也涉及業務理解、個人的成長&#xff0c;甚至是數據行業未來的價值。回顧過去的經歷&#xff0c;有很多問題反復出現&#xff0c;甚至成為繞不開的課題&am…

大文件分片上傳及斷點續傳實現

使用 支持分片上傳及斷點續傳 前端使用 vue 2 后端使用 springboot 源碼在私信

圖解AUTOSAR_SWS_IOHardwareAbstraction

AUTOSAR IO硬件抽象層詳解 基于AUTOSAR標準的IO硬件抽象層設計與實現指南 目錄 1. 概述2. 架構設計 2.1 模塊架構概覽2.2 內部組件結構2.3 與其他模塊的交互接口 3. 狀態機 3.1 狀態定義3.2 狀態轉換3.3 狀態行為 4. ADC信號處理流程 4.1 初始化流程4.2 轉換請求和處理4.3 通知…

Python正則表達式(一)

目錄 一、正則表達式的基本概念 1、基本概念 2、正則表達式的特殊字符 二、范圍符號和量詞 1、范圍符號 2、匹配漢字 3、量詞 三、正則表達式函數 1、使用正則表達式&#xff1a; 2、re.match()函數 3、re.search()函數 4、findall()函數 5、re.finditer()函數 6…

北京交通大學第三屆C語言積分賽

作者有言在先&#xff1a; 題解的作用是交流思路&#xff0c;不是抄作業的。可以把重點放在思路分析上而不是代碼上&#xff0c;畢竟每個人的代碼風格是不一樣的&#xff0c;看別人的代碼就跟做程序填空題一樣。先看明白思路再看代碼。 還有就是&#xff0c;deepseek真的很好用…