網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一、Struct結(jié)構(gòu)體
Go語(yǔ)言中沒(méi)有像C#、Java一樣的Class,只有Struct這樣的結(jié)構(gòu)體。Go語(yǔ)言使用type關(guān)鍵字來(lái)定義一個(gè)類型。
如下:
type User struct { Name string Age int32 Sex int16 AvatarUrl string }
二、Struct的聲明以及初始化
初始化方法一:直接定義,通過(guò)變量名.成員名的方式賦值
//初始化方法1 var user1 User user1.Name = "BigOrange" user1.Age = 20 user1.Sex = 1 user1.AvatarUrl = "xxxxxxx" fmt.Println("User1:",user1)
初始化方法二:直接通過(guò){}進(jìn)行初始化,這點(diǎn)和C#不一樣,C#初始化的時(shí)候一般用new,例如 var user = new User{xxxxx,xxxxx,xxxx}
//初始化方法2 var user2 User = User{ Name:"BigBanana", Age:23, Sex:0, AvatarUrl:"yyyyyyyyyyy", } fmt.Println("User2:",user2) //初始化方法2簡(jiǎn)化 user3 := User{ Name:"BigBanana", Age:23, Sex:0, AvatarUrl:"yyyyyyyyyyy", } fmt.Println("User3:",user3)
三、Struct的指針
Struct的指針比較簡(jiǎn)單,就是通過(guò)&獲取地址,此外還可以用new來(lái)返回一個(gè)對(duì)象的指針
方式一
var user4 *User = &User{ Name:"BigPeach", Age:22, Sex:1, AvatarUrl:"zzzzzzz", } fmt.Println("User4:",user4) fmt.Println("User4:",*user4)
方式二
user5 := new(User) user5.Name="BigGrape" user5.Age= 25 user5.Sex= 1 user5.AvatarUrl= "mmmmmmmmm" fmt.Println("User5:",user5) fmt.Println("User5:",*user5)
上面第二種方式可能會(huì)有些疑問(wèn),user5不是一個(gè)指針類型嗎?怎么和上面的值類型一樣直接用【變量名.成員】 的方式進(jìn)行賦值了呢? 不是應(yīng)該 (*user5).Name 這樣嗎?沒(méi)有錯(cuò)!
這是GO語(yǔ)言實(shí)現(xiàn)的一個(gè)語(yǔ)法糖,實(shí)際上GO語(yǔ)言會(huì)幫我轉(zhuǎn)換。
四、Struct成員的內(nèi)存布局以及實(shí)現(xiàn)構(gòu)造函數(shù)
例如下面這樣的一段代碼
package main import "fmt" type AddressDemo struct { addr1 int32 addr2 int32 addr3 int32 } func main(){ addr := new(AddressDemo) fmt.Println("add1地址:",&addr.addr1) fmt.Println("add2地址:",&addr.addr2) fmt.Println("add3地址:",&addr.addr3) }
結(jié)果:
add1地址: 0xc042060080
add2地址: 0xc042060084
add3地址: 0xc042060088
可以看出來(lái),addr1、addr2、addr3都是int32,都是占用了4個(gè)字節(jié),他們的地址分配都是連續(xù)的。
For example: 下面這個(gè)User包,就實(shí)現(xiàn)了一個(gè)NewUser的方法,他就是構(gòu)造函數(shù)
package User type User struct { Name string Age int32 Sex int16 AvatarUrl string } func NewUser(name string , age int32,sex int16,avatarUrl string) *User{ user:=new(User) user.Name = name user.Age = age user.Sex = sex user.AvatarUrl = avatarUrl return user }
五、Struct中的匿名字段和嵌套
可以像下面這樣聲明:后兩個(gè)字段沒(méi)有名字
type Class struct { Name string int string }
使用的時(shí)候,對(duì)于匿名的字段,直接賦值就可以了
class1:=Class{ Name:"Class1", int:123, string:"sssssss", } fmt.Println("class1:",class1)
結(jié)構(gòu)體的嵌套
type User struct { Name string Age int32 Sex int16 AvatarUrl string } type Class struct { Name string } type Student struct { User User Class Class }
使用:
func main() { stu:=new(User.Student) stu.Class = User.Class{ Name:"5-2", } stu.User = User.User { Name:"BigBanana", Sex:1, Age:12, AvatarUrl:"asdasdasd", } fmt.Println(stu) }
如果是匿名結(jié)構(gòu)體嵌套
呢?修改一下Student
type Student struct { User User Class }
使用在對(duì)Class這個(gè)成員進(jìn)行賦值的時(shí)候,可以發(fā)現(xiàn),既可以使用
stu.Class = User.Class{ Name:"5-2", }
也可以使用Name直接賦值,順序就是現(xiàn)在當(dāng)前的結(jié)構(gòu)體找,找不到再?gòu)哪涿Y(jié)構(gòu)體中查找,正好找到Class里面有Name
stu.Name = "5-2"
如果Class和User都是匿名結(jié)構(gòu)嵌套,但是他們里面都有Name,當(dāng)我們使用stu.Name的時(shí)候,那他訪問(wèn)的是Class里的Name還是User里面的Name? 那么豈不是沖突了? 如何處理沖突?
當(dāng)我試圖給stu.Name賦值的時(shí)候,編譯器報(bào)錯(cuò)了,內(nèi)容如下,也就是它找不到應(yīng)該給誰(shuí)賦值。
這時(shí)候要解決這個(gè)沖突,必須指定是哪個(gè)匿名字段里面的Name
stu:=new(User.Student) stu.User.Name = "123123" stu.Class.Name = "5-2" stu.User = User.User { Name:"BigBanana", Sex:1, Age:12, AvatarUrl:"asdasdasd", }
六、結(jié)構(gòu)體內(nèi)字段的可見(jiàn)性
和包一樣,小寫的字段外部不可見(jiàn),大寫的外部可見(jiàn)
七、結(jié)構(gòu)體的Tag
tag是結(jié)構(gòu)體的元信息,可以在運(yùn)行的時(shí)候通過(guò)反射的機(jī)制讀出來(lái)。
怎么寫tag?
以`作為開(kāi)頭和結(jié)尾,中間是key-value形式的字符串,每一個(gè)鍵值對(duì)以,作為分隔。例如
type User struct { UserName string `json:"userName",db:"User_Name"` Age int32 `json:"age"` Sex int16 `json:"sex"` AvatarUrl string `json:"avatarUrl",db:"Avatar_Url"` }
使用并運(yùn)行:
func main() { user := User.User { UserName:"BigBanana", Sex:1, Age:12, AvatarUrl:"asdasdasd", } fmt.Println(user) data,_:=json.Marshal(user) fmt.Println(string(data)) }
結(jié)果:
{"userName":"BigBanana","age":12,"sex":1,"avatarUrl":"asdasdasd"}
可以看到,如果打了這個(gè)tag,會(huì)顯示tag后面的標(biāo)記名稱。
此外:如果字段名稱是小寫,那么json輸出的時(shí)候就不會(huì)有這個(gè)字段被打印了。
原文鏈接:https://www.cnblogs.com/dcz2015/p/10770917.html
相關(guān)推薦
- 2023-07-06 springboot監(jiān)聽(tīng)Redis 緩存過(guò)期(Key 失效)事件
- 2022-04-02 Android中Button實(shí)現(xiàn)點(diǎn)擊換圖案及顏色_Android
- 2023-07-18 SpringBoot Cache 整合 Redis 緩存框架
- 2022-06-12 Python基于socket實(shí)現(xiàn)TCP客戶端和服務(wù)端_python
- 2022-07-23 C#中的隨機(jī)數(shù)函數(shù)Random()_C#教程
- 2022-11-22 Rust?Struct結(jié)構(gòu)體詳解_Rust語(yǔ)言
- 2022-11-10 Rust?use關(guān)鍵字妙用及模塊內(nèi)容拆分方法_相關(guān)技巧
- 2022-08-31 python中函數(shù)的參數(shù)詳解_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支